Bug 1988114. r=ahale a=dmeehan

Differential Revision: https://phabricator.services.mozilla.com/D264683
This commit is contained in:
Lee Salzman
2025-09-16 14:35:44 +00:00
committed by dmeehan@mozilla.com
parent 6f08eaa188
commit 35523c86dc
2 changed files with 39 additions and 10 deletions

View File

@@ -526,6 +526,9 @@ bool CanvasTranslator::TryDrawTargetWebglFallback(
NotifyRequiresRefresh(aTextureOwnerId); NotifyRequiresRefresh(aTextureOwnerId);
const auto& info = mTextureInfo[aTextureOwnerId]; const auto& info = mTextureInfo[aTextureOwnerId];
if (info.mTextureData) {
return true;
}
if (RefPtr<gfx::DrawTarget> dt = if (RefPtr<gfx::DrawTarget> dt =
CreateFallbackDrawTarget(info.mRefPtr, aTextureOwnerId, CreateFallbackDrawTarget(info.mRefPtr, aTextureOwnerId,
aWebgl->GetSize(), aWebgl->GetFormat())) { aWebgl->GetSize(), aWebgl->GetFormat())) {
@@ -926,6 +929,9 @@ void CanvasTranslator::DeviceResetAcknowledged() { DeviceChangeAcknowledged(); }
bool CanvasTranslator::CreateReferenceTexture() { bool CanvasTranslator::CreateReferenceTexture() {
if (mReferenceTextureData) { if (mReferenceTextureData) {
if (mBaseDT) {
mReferenceTextureData->ReturnDrawTarget(mBaseDT.forget());
}
mReferenceTextureData->Unlock(); mReferenceTextureData->Unlock();
} }
@@ -1097,14 +1103,12 @@ void CanvasTranslator::PrepareShmem(
const RemoteTextureOwnerId aTextureOwnerId) { const RemoteTextureOwnerId aTextureOwnerId) {
if (gfx::DrawTargetWebgl* webgl = if (gfx::DrawTargetWebgl* webgl =
GetDrawTargetWebgl(aTextureOwnerId, false)) { GetDrawTargetWebgl(aTextureOwnerId, false)) {
if (const auto& fallback = mTextureInfo[aTextureOwnerId].mTextureData) { if (RefPtr<gfx::DrawTarget> dt =
mTextureInfo[aTextureOwnerId].mFallbackDrawTarget) {
// If there was a fallback, copy the fallback to the software framebuffer // If there was a fallback, copy the fallback to the software framebuffer
// shmem for reading. // shmem for reading.
if (RefPtr<gfx::DrawTarget> dt = fallback->BorrowDrawTarget()) { if (RefPtr<gfx::SourceSurface> snapshot = dt->Snapshot()) {
if (RefPtr<gfx::SourceSurface> snapshot = dt->Snapshot()) { webgl->CopySurface(snapshot, snapshot->GetRect(), gfx::IntPoint(0, 0));
webgl->CopySurface(snapshot, snapshot->GetRect(),
gfx::IntPoint(0, 0));
}
} }
} else { } else {
// Otherwise, just ensure the software framebuffer is up to date. // Otherwise, just ensure the software framebuffer is up to date.
@@ -1207,6 +1211,7 @@ already_AddRefed<gfx::DrawTarget> CanvasTranslator::CreateFallbackDrawTarget(
TextureInfo& info = mTextureInfo[aTextureOwnerId]; TextureInfo& info = mTextureInfo[aTextureOwnerId];
info.mRefPtr = aRefPtr; info.mRefPtr = aRefPtr;
info.mFallbackDrawTarget = dt;
info.mTextureData = std::move(textureData); info.mTextureData = std::move(textureData);
info.mTextureLockMode = kInitMode; info.mTextureLockMode = kInitMode;
} while (!dt && CheckForFreshCanvasDevice(__LINE__)); } while (!dt && CheckForFreshCanvasDevice(__LINE__));
@@ -1223,6 +1228,19 @@ already_AddRefed<gfx::DrawTarget> CanvasTranslator::CreateDrawTarget(
return nullptr; return nullptr;
} }
{
auto result = mTextureInfo.find(aTextureOwnerId);
if (result != mTextureInfo.end()) {
const TextureInfo& info = result->second;
if (info.mTextureData || info.mDrawTarget) {
#ifndef FUZZING_SNAPSHOT
MOZ_DIAGNOSTIC_CRASH("DrawTarget already exists");
#endif
return nullptr;
}
}
}
RefPtr<gfx::DrawTarget> dt; RefPtr<gfx::DrawTarget> dt;
if (gfx::gfxVars::UseAcceleratedCanvas2D()) { if (gfx::gfxVars::UseAcceleratedCanvas2D()) {
if (EnsureSharedContextWebgl()) { if (EnsureSharedContextWebgl()) {
@@ -1287,7 +1305,11 @@ void CanvasTranslator::RemoveTexture(const RemoteTextureOwnerId aTextureOwnerId,
if (--info.mLocked > 0) { if (--info.mLocked > 0) {
return; return;
} }
RemoveDrawTarget(info.mRefPtr);
if (info.mTextureData) { if (info.mTextureData) {
if (info.mFallbackDrawTarget) {
info.mTextureData->ReturnDrawTarget(info.mFallbackDrawTarget.forget());
}
info.mTextureData->Unlock(); info.mTextureData->Unlock();
} }
if (mRemoteTextureOwner) { if (mRemoteTextureOwner) {
@@ -1455,9 +1477,13 @@ void CanvasTranslator::ClearTextureInfo() {
mUsedWrapperForSurfaceDescriptor = nullptr; mUsedWrapperForSurfaceDescriptor = nullptr;
mUsedSurfaceDescriptorForSurfaceDescriptor = Nothing(); mUsedSurfaceDescriptorForSurfaceDescriptor = Nothing();
for (auto const& entry : mTextureInfo) { for (auto& entry : mTextureInfo) {
if (entry.second.mTextureData) { auto& info = entry.second;
entry.second.mTextureData->Unlock(); if (info.mTextureData) {
if (info.mFallbackDrawTarget) {
info.mTextureData->ReturnDrawTarget(info.mFallbackDrawTarget.forget());
}
info.mTextureData->Unlock();
} }
} }
mTextureInfo.clear(); mTextureInfo.clear();
@@ -1470,8 +1496,10 @@ void CanvasTranslator::ClearTextureInfo() {
if (sSharedContext && sSharedContext->hasOneRef()) { if (sSharedContext && sSharedContext->hasOneRef()) {
sSharedContext->ClearCaches(); sSharedContext->ClearCaches();
} }
mBaseDT = nullptr;
if (mReferenceTextureData) { if (mReferenceTextureData) {
if (mBaseDT) {
mReferenceTextureData->ReturnDrawTarget(mBaseDT.forget());
}
mReferenceTextureData->Unlock(); mReferenceTextureData->Unlock();
} }
if (mRemoteTextureOwner) { if (mRemoteTextureOwner) {

View File

@@ -560,6 +560,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
gfx::ReferencePtr mRefPtr; gfx::ReferencePtr mRefPtr;
UniquePtr<TextureData> mTextureData; UniquePtr<TextureData> mTextureData;
RefPtr<gfx::DrawTarget> mDrawTarget; RefPtr<gfx::DrawTarget> mDrawTarget;
RefPtr<gfx::DrawTarget> mFallbackDrawTarget;
bool mNotifiedRequiresRefresh = false; bool mNotifiedRequiresRefresh = false;
// Ref-count of how active uses of the DT. Avoids deletion when locked. // Ref-count of how active uses of the DT. Avoids deletion when locked.
int32_t mLocked = 1; int32_t mLocked = 1;