mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1428558
- Part 1. Streamline mappings between an ImageKey and an ExternalImageId for shared surfaces. r=nical
Async animated images need a single ImageKey which can point to any frame represented by its own external image ID. Additionally a frame could be referenced again directly (e.g. something shows/uses the first frame of the animated image). Before this patch, the ownership between an ImageKey and an external image ID for a shared surface was not clearly expressed. This resulted in a special command to release the reference to the external image separately from deleting the image key. This patch makes the strong reference to an external image ID and an ImageKey directly related. Not only does this facilitate multiple ImageKeys owning the same surface, it also simplifies the ownership semantics. Differential Revision: https://phabricator.services.mozilla.com/D7520
This commit is contained in:
parent
1395b7eef1
commit
83a52f66de
@ -422,14 +422,8 @@ SharedSurfacesChild::Unshare(const wr::ExternalImageId& aId,
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
for (const auto& entry : aKeys) {
|
||||
if (entry.mManager->IsDestroyed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entry.mManager->AddImageKeyForDiscard(entry.mImageKey);
|
||||
WebRenderBridgeChild* wrBridge = entry.mManager->WrBridge();
|
||||
if (wrBridge) {
|
||||
wrBridge->DeallocExternalImageId(aId);
|
||||
if (!entry.mManager->IsDestroyed()) {
|
||||
entry.mManager->AddImageKeyForDiscard(entry.mImageKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,10 +73,6 @@ struct OpRemovePipelineIdForCompositable {
|
||||
PipelineId pipelineId;
|
||||
};
|
||||
|
||||
struct OpRemoveExternalImageId {
|
||||
ExternalImageId externalImageId;
|
||||
};
|
||||
|
||||
struct OpReleaseTextureOfImage {
|
||||
ImageKey key;
|
||||
};
|
||||
@ -97,7 +93,6 @@ struct OpUpdatedAsyncImagePipeline {
|
||||
union WebRenderParentCommand {
|
||||
OpAddPipelineIdForCompositable;
|
||||
OpRemovePipelineIdForCompositable;
|
||||
OpRemoveExternalImageId;
|
||||
OpReleaseTextureOfImage;
|
||||
OpUpdateAsyncImagePipeline;
|
||||
OpUpdatedAsyncImagePipeline;
|
||||
|
@ -222,13 +222,6 @@ WebRenderBridgeChild::GetNextExternalImageId()
|
||||
return id.value();
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeChild::DeallocExternalImageId(const wr::ExternalImageId& aImageId)
|
||||
{
|
||||
AddWebRenderParentCommand(
|
||||
OpRemoveExternalImageId(aImageId));
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeChild::ReleaseTextureOfImage(const wr::ImageKey& aKey)
|
||||
{
|
||||
|
@ -101,8 +101,6 @@ public:
|
||||
const CompositableHandle& aHandlee);
|
||||
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId);
|
||||
|
||||
void DeallocExternalImageId(const wr::ExternalImageId& aImageId);
|
||||
|
||||
/// Release TextureClient that is bounded to ImageKey.
|
||||
/// It is used for recycling TextureClient.
|
||||
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
|
||||
|
@ -426,7 +426,7 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
|
||||
}
|
||||
case OpUpdateResource::TOpDeleteImage: {
|
||||
const auto& op = cmd.get_OpDeleteImage();
|
||||
aUpdates.DeleteImage(op.key());
|
||||
DeleteImage(op.key(), aUpdates);
|
||||
break;
|
||||
}
|
||||
case OpUpdateResource::TOpDeleteFont: {
|
||||
@ -456,29 +456,30 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> dSurf = SharedSurfacesParent::Acquire(aExtId);
|
||||
if (dSurf) {
|
||||
auto it = mSharedSurfaceIds.emplace(wr::AsUint64(aExtId));
|
||||
if (!it.second) {
|
||||
// We already have a mapping for this image, so decrement the ownership
|
||||
// counter just increased unnecessarily. This can happen when an image is
|
||||
// slow to decode and we need to invalidate it by updating its image key.
|
||||
SharedSurfacesParent::Release(aExtId);
|
||||
}
|
||||
auto key = wr::AsUint64(aKey);
|
||||
auto it = mSharedSurfaceIds.find(key);
|
||||
if (it != mSharedSurfaceIds.end()) {
|
||||
gfxCriticalNote << "Readding known shared surface: " << key;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gfxEnv::EnableWebRenderRecording()) {
|
||||
wr::ImageDescriptor descriptor(dSurf->GetSize(), dSurf->Stride(),
|
||||
dSurf->GetFormat());
|
||||
aResources.AddExternalImage(aKey, descriptor, aExtId,
|
||||
wr::WrExternalImageBufferType::ExternalBuffer,
|
||||
0);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
RefPtr<DataSourceSurface> dSurf = SharedSurfacesParent::Acquire(aExtId);
|
||||
if (!dSurf) {
|
||||
gfxCriticalNote << "DataSourceSurface of SharedSurfaces does not exist for extId:" << wr::AsUint64(aExtId);
|
||||
return false;
|
||||
}
|
||||
|
||||
mSharedSurfaceIds.insert(std::make_pair(key, aExtId));
|
||||
|
||||
if (!gfxEnv::EnableWebRenderRecording()) {
|
||||
wr::ImageDescriptor descriptor(dSurf->GetSize(), dSurf->Stride(),
|
||||
dSurf->GetFormat());
|
||||
aResources.AddExternalImage(aKey, descriptor, aExtId,
|
||||
wr::WrExternalImageBufferType::ExternalBuffer,
|
||||
0);
|
||||
return true;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface map;
|
||||
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
|
||||
gfxCriticalNote << "DataSourceSurface failed to map for Image for extId:" << wr::AsUint64(aExtId);
|
||||
@ -570,18 +571,32 @@ WebRenderBridgeParent::UpdateExternalImage(wr::ExternalImageId aExtId,
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t imageId = wr::AsUint64(aExtId);
|
||||
if (mSharedSurfaceIds.find(imageId) == mSharedSurfaceIds.end()) {
|
||||
gfxCriticalNote << "Updating unknown shared surface: " << wr::AsUint64(aExtId);
|
||||
auto key = wr::AsUint64(aKey);
|
||||
auto it = mSharedSurfaceIds.find(key);
|
||||
if (it == mSharedSurfaceIds.end()) {
|
||||
gfxCriticalNote << "Updating unknown shared surface: " << key;
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> dSurf = SharedSurfacesParent::Get(aExtId);
|
||||
RefPtr<DataSourceSurface> dSurf;
|
||||
if (it->second == aExtId) {
|
||||
dSurf = SharedSurfacesParent::Get(aExtId);
|
||||
} else {
|
||||
dSurf = SharedSurfacesParent::Acquire(aExtId);
|
||||
}
|
||||
|
||||
if (!dSurf) {
|
||||
gfxCriticalNote << "Shared surface does not exist for extId:" << wr::AsUint64(aExtId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(it->second == aExtId)) {
|
||||
// We already have a mapping for this image key, so ensure we release the
|
||||
// previous external image ID.
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, it->second);
|
||||
it->second = aExtId;
|
||||
}
|
||||
|
||||
if (!gfxEnv::EnableWebRenderRecording()) {
|
||||
wr::ImageDescriptor descriptor(dSurf->GetSize(), dSurf->Stride(),
|
||||
dSurf->GetFormat());
|
||||
@ -1036,11 +1051,6 @@ WebRenderBridgeParent::ProcessWebRenderParentCommands(const InfallibleTArray<Web
|
||||
RemovePipelineIdForCompositable(op.pipelineId(), aTxn);
|
||||
break;
|
||||
}
|
||||
case WebRenderParentCommand::TOpRemoveExternalImageId: {
|
||||
const OpRemoveExternalImageId& op = cmd.get_OpRemoveExternalImageId();
|
||||
RemoveExternalImageId(op.externalImageId());
|
||||
break;
|
||||
}
|
||||
case WebRenderParentCommand::TOpReleaseTextureOfImage: {
|
||||
const OpReleaseTextureOfImage& op = cmd.get_OpReleaseTextureOfImage();
|
||||
ReleaseTextureOfImage(op.key());
|
||||
@ -1274,17 +1284,20 @@ WebRenderBridgeParent::RemovePipelineIdForCompositable(const wr::PipelineId& aPi
|
||||
}
|
||||
|
||||
void
|
||||
WebRenderBridgeParent::RemoveExternalImageId(const ExternalImageId& aImageId)
|
||||
WebRenderBridgeParent::DeleteImage(const ImageKey& aKey,
|
||||
wr::TransactionBuilder& aUpdates)
|
||||
{
|
||||
if (mDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t imageId = wr::AsUint64(aImageId);
|
||||
if (mSharedSurfaceIds.find(imageId) != mSharedSurfaceIds.end()) {
|
||||
mSharedSurfaceIds.erase(imageId);
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, aImageId);
|
||||
auto it = mSharedSurfaceIds.find(wr::AsUint64(aKey));
|
||||
if (it != mSharedSurfaceIds.end()) {
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, it->second);
|
||||
mSharedSurfaceIds.erase(it);
|
||||
}
|
||||
|
||||
aUpdates.DeleteImage(aKey);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1858,8 +1871,7 @@ WebRenderBridgeParent::ClearResources()
|
||||
}
|
||||
mAsyncCompositables.clear();
|
||||
for (const auto& entry : mSharedSurfaceIds) {
|
||||
wr::ExternalImageId id = wr::ToExternalImageId(entry);
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, id);
|
||||
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, entry.second);
|
||||
}
|
||||
mSharedSurfaceIds.clear();
|
||||
|
||||
|
@ -249,7 +249,8 @@ private:
|
||||
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId,
|
||||
wr::TransactionBuilder& aTxn);
|
||||
|
||||
void RemoveExternalImageId(const ExternalImageId& aImageId);
|
||||
void DeleteImage(const wr::ImageKey& aKey,
|
||||
wr::TransactionBuilder& aUpdates);
|
||||
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
|
||||
|
||||
LayersId GetLayersId() const;
|
||||
@ -335,7 +336,7 @@ private:
|
||||
std::unordered_set<uint64_t> mActiveAnimations;
|
||||
std::unordered_map<uint64_t, RefPtr<WebRenderImageHost>> mAsyncCompositables;
|
||||
std::unordered_map<uint64_t, CompositableTextureHostRef> mTextureHosts;
|
||||
std::unordered_set<uint64_t> mSharedSurfaceIds;
|
||||
std::unordered_map<uint64_t, wr::ExternalImageId> mSharedSurfaceIds;
|
||||
|
||||
TimeDuration mVsyncRate;
|
||||
TimeStamp mPreviousFrameTimeStamp;
|
||||
|
Loading…
Reference in New Issue
Block a user