Bug 1472951 - Remove ExternalImageId allocation for ImageClient r=nical

This commit is contained in:
sotaro 2018-07-06 21:25:33 +09:00
Родитель 76ff8da0e0
Коммит 3acc79b45a
13 изменённых файлов: 162 добавлений и 118 удалений

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

@ -260,6 +260,15 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlag
return true;
}
RefPtr<TextureClient>
ImageClientSingle::GetForwardedTexture()
{
if (mBuffers.Length() == 0) {
return nullptr;
}
return mBuffers[0].mTextureClient;
}
bool
ImageClientSingle::AddTextureClient(TextureClient* aTexture)
{

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

@ -73,6 +73,8 @@ public:
uint32_t GetLastUpdateGenerationCounter() { return mLastUpdateGenerationCounter; }
virtual RefPtr<TextureClient> GetForwardedTexture() { return nullptr; }
protected:
ImageClient(CompositableForwarder* aFwd, TextureFlags aFlags,
CompositableType aType);
@ -104,6 +106,8 @@ public:
ImageClientSingle* AsImageClientSingle() override { return this; }
virtual RefPtr<TextureClient> GetForwardedTexture() override;
bool IsEmpty() { return mBuffers.IsEmpty(); }
protected:

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

@ -653,6 +653,8 @@ public:
// must only be called from the PaintThread.
void DropPaintThreadRef();
wr::MaybeExternalImageId GetExternalImageKey() { return mExternalImageId; }
private:
static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure);

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

@ -51,6 +51,12 @@ struct OpAddExternalImage {
ImageKey key;
};
struct OpAddExternalImageForTexture {
ExternalImageId externalImageId;
ImageKey key;
PTexture texture;
};
struct OpAddCompositorAnimations {
CompositorAnimations data;
};
@ -65,15 +71,14 @@ struct OpRemovePipelineIdForCompositable {
PipelineId pipelineId;
};
struct OpAddExternalImageIdForCompositable {
ExternalImageId externalImageId;
CompositableHandle handle;
};
struct OpRemoveExternalImageId {
ExternalImageId externalImageId;
};
struct OpReleaseTextureOfImage {
ImageKey key;
};
struct OpUpdateAsyncImagePipeline {
PipelineId pipelineId;
LayoutDeviceRect scBounds;
@ -86,8 +91,8 @@ struct OpUpdateAsyncImagePipeline {
union WebRenderParentCommand {
OpAddPipelineIdForCompositable;
OpRemovePipelineIdForCompositable;
OpAddExternalImageIdForCompositable;
OpRemoveExternalImageId;
OpReleaseTextureOfImage;
OpUpdateAsyncImagePipeline;
CompositableOperation;
OpAddCompositorAnimations;
@ -171,6 +176,7 @@ union OpUpdateResource {
OpAddFontInstance;
OpDeleteFontInstance;
OpAddExternalImage;
OpAddExternalImageForTexture;
};
} // namespace

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

@ -9,6 +9,7 @@
#include <algorithm>
#include "mozilla/Maybe.h"
#include "mozilla/ipc/SharedMemory.h"
#include "mozilla/layers/PTextureChild.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
namespace mozilla {
@ -279,6 +280,17 @@ IpcResourceUpdateQueue::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKe
mUpdates.AppendElement(layers::OpAddExternalImage(aExtId, aKey));
}
void
IpcResourceUpdateQueue::AddExternalImageForTexture(wr::ExternalImageId aExtId,
wr::ImageKey aKey,
layers::TextureClient* aTexture)
{
MOZ_ASSERT(aTexture);
MOZ_ASSERT(aTexture->GetIPDLActor());
MOZ_RELEASE_ASSERT(aTexture->GetIPDLActor()->GetIPCChannel() == mWriter.WrBridge()->GetIPCChannel());
mUpdates.AppendElement(layers::OpAddExternalImageForTexture(aExtId, aKey, nullptr, aTexture->GetIPDLActor()));
}
bool
IpcResourceUpdateQueue::UpdateImageBuffer(ImageKey aKey,
const ImageDescriptor& aDescriptor,

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

@ -37,6 +37,8 @@ public:
void Clear();
bool IsEmpty() const;
layers::WebRenderBridgeChild* WrBridge() const { return mShmAllocator; }
protected:
bool AllocChunk();
layers::OffsetRange AllocLargeChunk(size_t aSize);
@ -83,6 +85,10 @@ public:
void AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey);
void AddExternalImageForTexture(wr::ExternalImageId aExtId,
wr::ImageKey aKey,
layers::TextureClient* aTexture);
bool UpdateImageBuffer(wr::ImageKey aKey,
const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes);

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

@ -221,15 +221,6 @@ WebRenderBridgeChild::GetNextExternalImageId()
return id.value();
}
wr::ExternalImageId
WebRenderBridgeChild::AllocExternalImageIdForCompositable(CompositableClient* aCompositable)
{
wr::ExternalImageId imageId = GetNextExternalImageId();
AddWebRenderParentCommand(
OpAddExternalImageIdForCompositable(imageId, aCompositable->GetIPCHandle()));
return imageId;
}
void
WebRenderBridgeChild::DeallocExternalImageId(const wr::ExternalImageId& aImageId)
{
@ -237,6 +228,13 @@ WebRenderBridgeChild::DeallocExternalImageId(const wr::ExternalImageId& aImageId
OpRemoveExternalImageId(aImageId));
}
void
WebRenderBridgeChild::ReleaseTextureOfImage(const wr::ImageKey& aKey)
{
AddWebRenderParentCommand(
OpReleaseTextureOfImage(aKey));
}
struct FontFileDataSink
{
wr::FontKey* mFontKey;

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

@ -100,9 +100,12 @@ public:
const CompositableHandle& aHandlee);
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId);
wr::ExternalImageId AllocExternalImageIdForCompositable(CompositableClient* aCompositable);
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);
/**
* Clean this up, finishing with SendShutDown() which will cause __delete__
* to be sent from the parent side.

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

@ -344,6 +344,15 @@ WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResour
}
break;
}
case OpUpdateResource::TOpAddExternalImageForTexture: {
const auto& op = cmd.get_OpAddExternalImageForTexture();
CompositableTextureHostRef texture;
texture = TextureHost::AsTextureHost(op.textureParent());
if (!AddExternalImageForTexture(op.externalImageId(), op.key(), texture, aUpdates)) {
return false;
}
break;
}
case OpUpdateResource::TOpAddRawFont: {
const auto& op = cmd.get_OpAddRawFont();
wr::Vec<uint8_t> bytes;
@ -426,29 +435,54 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
return true;
}
} else {
MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(aExtId)).get());
RefPtr<WebRenderImageHost> host = mExternalImageIds.Get(wr::AsUint64(aExtId));
if (!host) {
gfxCriticalNote << "CompositableHost does not exist for extId:" << wr::AsUint64(aExtId);
return false;
}
if (!gfxEnv::EnableWebRenderRecording()) {
TextureHost* texture = host->GetAsTextureHostForComposite();
if (!texture) {
gfxCriticalNote << "TextureHost does not exist for extId:" << wr::AsUint64(aExtId);
return false;
}
WebRenderTextureHost* wrTexture = texture->AsWebRenderTextureHost();
if (wrTexture) {
wrTexture->PushResourceUpdates(aResources, TextureHost::ADD_IMAGE, keys,
wrTexture->GetExternalImageKey());
return true;
}
}
dSurf = host->GetAsSurface();
gfxCriticalNote << "DataSourceSurface of SharedSurfaces does not exist for extId:" << wr::AsUint64(aExtId);
return false;
}
DataSourceSurface::MappedSurface map;
if (!dSurf->Map(gfx::DataSourceSurface::MapType::READ, &map)) {
gfxCriticalNote << "DataSourceSurface failed to map for Image for extId:" << wr::AsUint64(aExtId);
return false;
}
IntSize size = dSurf->GetSize();
wr::ImageDescriptor descriptor(size, map.mStride, dSurf->GetFormat());
wr::Vec<uint8_t> data;
data.PushBytes(Range<uint8_t>(map.mData, size.height * map.mStride));
aResources.AddImage(keys[0], descriptor, data);
dSurf->Unmap();
return true;
}
bool
WebRenderBridgeParent::AddExternalImageForTexture(wr::ExternalImageId aExtId,
wr::ImageKey aKey,
TextureHost* aTexture,
wr::TransactionBuilder& aResources)
{
Range<wr::ImageKey> keys(&aKey, 1);
// Check if key is obsoleted.
if (keys[0].mNamespace != mIdNamespace) {
return true;
}
if(!aTexture) {
gfxCriticalNote << "TextureHost does not exist for extId:" << wr::AsUint64(aExtId);
return false;
}
if (!gfxEnv::EnableWebRenderRecording()) {
WebRenderTextureHost* wrTexture = aTexture->AsWebRenderTextureHost();
if (wrTexture) {
wrTexture->PushResourceUpdates(aResources, TextureHost::ADD_IMAGE, keys,
wrTexture->GetExternalImageKey());
MOZ_ASSERT(!mTextureHosts.Get(wr::AsUint64(aKey), nullptr));
mTextureHosts.Put(wr::AsUint64(aKey), CompositableTextureHostRef(aTexture));
return true;
}
}
RefPtr<DataSourceSurface> dSurf = aTexture->GetAsSurface();
if (!dSurf) {
gfxCriticalNote << "TextureHost does not return DataSourceSurface for extId:" << wr::AsUint64(aExtId);
return false;
@ -847,17 +881,16 @@ WebRenderBridgeParent::ProcessWebRenderParentCommands(const InfallibleTArray<Web
RemovePipelineIdForCompositable(op.pipelineId(), aTxn);
break;
}
case WebRenderParentCommand::TOpAddExternalImageIdForCompositable: {
const OpAddExternalImageIdForCompositable& op = cmd.get_OpAddExternalImageIdForCompositable();
AddExternalImageIdForCompositable(op.externalImageId(),
op.handle());
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());
break;
}
case WebRenderParentCommand::TOpUpdateAsyncImagePipeline: {
const OpUpdateAsyncImagePipeline& op = cmd.get_OpUpdateAsyncImagePipeline();
mAsyncImageManager->UpdateAsyncImagePipeline(op.pipelineId(),
@ -1064,33 +1097,6 @@ WebRenderBridgeParent::RemovePipelineIdForCompositable(const wr::PipelineId& aPi
return;
}
void
WebRenderBridgeParent::AddExternalImageIdForCompositable(const ExternalImageId& aImageId,
const CompositableHandle& aHandle)
{
if (mDestroyed) {
return;
}
MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
RefPtr<CompositableHost> host = FindCompositable(aHandle);
WebRenderImageHost* wrHost = host->AsWebRenderImageHost();
MOZ_ASSERT(wrHost);
if (!wrHost) {
gfxCriticalNote << "Incompatible CompositableHost for external image at WebRenderBridgeParent.";
}
if (!wrHost) {
return;
}
wrHost->SetWrBridge(this);
mExternalImageIds.Put(wr::AsUint64(aImageId), wrHost);
return;
}
void
WebRenderBridgeParent::RemoveExternalImageId(const ExternalImageId& aImageId)
{
@ -1101,18 +1107,27 @@ WebRenderBridgeParent::RemoveExternalImageId(const ExternalImageId& aImageId)
uint64_t imageId = wr::AsUint64(aImageId);
if (mSharedSurfaceIds.EnsureRemoved(imageId)) {
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, aImageId);
}
}
void
WebRenderBridgeParent::ReleaseTextureOfImage(const wr::ImageKey& aKey)
{
if (mDestroyed) {
return;
}
WebRenderImageHost* wrHost = mExternalImageIds.Get(imageId).get();
if (!wrHost) {
return;
uint64_t id = wr::AsUint64(aKey);
CompositableTextureHostRef texture;
WebRenderTextureHost* wrTexture = nullptr;
if (mTextureHosts.Get(id, &texture)) {
wrTexture = texture->AsWebRenderTextureHost();
}
wrHost->ClearWrBridge();
mExternalImageIds.Remove(imageId);
return;
if (wrTexture) {
mAsyncImageManager->HoldExternalImage(mPipelineId, mWrEpoch, wrTexture);
}
mTextureHosts.Remove(id);
}
mozilla::ipc::IPCResult
@ -1639,10 +1654,14 @@ WebRenderBridgeParent::ClearResources()
// Schedule generate frame to clean up Pipeline
ScheduleGenerateFrame();
// WrFontKeys and WrImageKeys are deleted during WebRenderAPI destruction.
for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
iter.Data()->ClearWrBridge();
for (auto iter = mTextureHosts.Iter(); !iter.Done(); iter.Next()) {
WebRenderTextureHost* wrTexture = iter.Data()->AsWebRenderTextureHost();
MOZ_ASSERT(wrTexture);
if (wrTexture) {
mAsyncImageManager->HoldExternalImage(mPipelineId, wrEpoch, wrTexture);
}
}
mExternalImageIds.Clear();
mTextureHosts.Clear();
for (auto iter = mAsyncCompositables.Iter(); !iter.Done(); iter.Next()) {
wr::PipelineId pipelineId = wr::AsPipelineId(iter.Key());
RefPtr<WebRenderImageHost> host = iter.Data();

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

@ -209,15 +209,19 @@ private:
bool AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey,
wr::TransactionBuilder& aResources);
bool AddExternalImageForTexture(wr::ExternalImageId aExtId,
wr::ImageKey aKey,
TextureHost* aTexture,
wr::TransactionBuilder& aResources);
void AddPipelineIdForCompositable(const wr::PipelineId& aPipelineIds,
const CompositableHandle& aHandle,
const bool& aAsync);
void RemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId,
wr::TransactionBuilder& aTxn);
void AddExternalImageIdForCompositable(const ExternalImageId& aImageId,
const CompositableHandle& aHandle);
void RemoveExternalImageId(const ExternalImageId& aImageId);
void ReleaseTextureOfImage(const wr::ImageKey& aKey);
LayersId GetLayersId() const;
void ProcessWebRenderParentCommands(const InfallibleTArray<WebRenderParentCommand>& aCommands,
@ -291,7 +295,7 @@ private:
// destroyed abnormally and Tab move between different windows.
std::unordered_set<uint64_t> mActiveAnimations;
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mAsyncCompositables;
nsDataHashtable<nsUint64HashKey, RefPtr<WebRenderImageHost>> mExternalImageIds;
nsDataHashtable<nsUint64HashKey, CompositableTextureHostRef> mTextureHosts;
nsTHashtable<nsUint64HashKey> mSharedSurfaceIds;
TimeDuration mVsyncRate;

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

@ -196,20 +196,6 @@ WebRenderImageHost::SetCurrentTextureHost(TextureHost* aTexture)
return;
}
if (mWrBridge &&
!mUseAsyncImagePipeline &&
!!mCurrentTextureHost &&
mCurrentTextureHost != aTexture &&
mCurrentTextureHost->AsWebRenderTextureHost()) {
MOZ_ASSERT(mWrBridge->AsyncImageManager());
wr::PipelineId piplineId = mWrBridge->PipelineId();
wr::Epoch epoch = mWrBridge->WrEpoch();
mWrBridge->AsyncImageManager()->HoldExternalImage(
piplineId,
epoch,
mCurrentTextureHost->AsWebRenderTextureHost());
}
mCurrentTextureHost = aTexture;
}

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

@ -78,10 +78,6 @@ WebRenderImageData::~WebRenderImageData()
{
ClearImageKey();
if (mExternalImageId) {
WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
}
if (mPipelineId) {
WrBridge()->RemovePipelineIdForCompositable(mPipelineId.ref());
}
@ -95,10 +91,15 @@ WebRenderImageData::ClearImageKey()
// key when appropriate.
if (mOwnsKey) {
mWRManager->AddImageKeyForDiscard(mKey.value());
if (mTextureOfImage) {
WrBridge()->ReleaseTextureOfImage(mKey.value());
mTextureOfImage = nullptr;
}
}
mKey.reset();
}
mOwnsKey = false;
MOZ_ASSERT(!mTextureOfImage);
}
Maybe<wr::ImageKey>
@ -132,9 +133,7 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
}
CreateImageClientIfNeeded();
CreateExternalImageIfNeeded();
if (!mImageClient || !mExternalImageId) {
if (!mImageClient) {
return Nothing();
}
@ -144,7 +143,8 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
uint32_t oldCounter = imageClient->GetLastUpdateGenerationCounter();
bool ret = imageClient->UpdateImage(aContainer, /* unused */0);
if (!ret || imageClient->IsEmpty()) {
RefPtr<TextureClient> currentTexture = imageClient->GetForwardedTexture();
if (!ret || !currentTexture) {
// Delete old key
ClearImageKey();
return Nothing();
@ -159,8 +159,13 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
// TODO(nical): noooo... we need to reuse image keys.
ClearImageKey();
wr::MaybeExternalImageId extId = currentTexture->GetExternalImageKey();
MOZ_RELEASE_ASSERT(extId.isSome());
MOZ_ASSERT(!mTextureOfImage);
key = WrBridge()->GetNextImageKey();
aResources.AddExternalImage(mExternalImageId.value(), key);
aResources.AddExternalImageForTexture(extId.ref(), key, currentTexture);
mTextureOfImage = currentTexture;
mKey = Some(key);
mOwnsKey = true;
@ -212,7 +217,6 @@ WebRenderImageData::CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBu
mContainer = aContainer;
}
MOZ_ASSERT(!mImageClient);
MOZ_ASSERT(!mExternalImageId);
// Push IFrame for async image pipeline.
//
@ -248,14 +252,6 @@ WebRenderImageData::CreateImageClientIfNeeded()
}
}
void
WebRenderImageData::CreateExternalImageIfNeeded()
{
if (!mExternalImageId) {
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
}
}
WebRenderFallbackData::WebRenderFallbackData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
: WebRenderImageData(aWRManager, aItem)
, mInvalid(false)

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

@ -151,9 +151,8 @@ public:
protected:
void ClearImageKey();
void CreateExternalImageIfNeeded();
wr::MaybeExternalImageId mExternalImageId;
RefPtr<TextureClient> mTextureOfImage;
Maybe<wr::ImageKey> mKey;
RefPtr<ImageClient> mImageClient;
Maybe<wr::PipelineId> mPipelineId;