Bug 1393031 - Use the ResourceUpdateQueue API on the content side. r=jrmuizel

This commit is contained in:
Nicolas Silva 2017-09-04 13:59:36 +02:00
parent 09e43ac029
commit 4b7b1e5992
13 changed files with 71 additions and 239 deletions

View File

@ -47,20 +47,7 @@ parent:
async InitReadLocks(ReadLockInit[] locks);
sync Create(IntSize aSize);
async UpdateResources(ByteBuffer aUpdates);
async AddImage(ImageKey aImageKey, IntSize aSize, uint32_t aStride,
SurfaceFormat aFormat, ByteBuffer aBytes);
async AddBlobImage(ImageKey aImageKey, IntSize aSize, uint32_t aStride,
SurfaceFormat aFormat, ByteBuffer aBytes);
async UpdateImage(ImageKey aImageKey, IntSize aSize,
SurfaceFormat aFormat, ByteBuffer aBytes);
async DeleteImage(ImageKey aImageKey);
async DeleteCompositorAnimations(uint64_t[] aIds);
async AddRawFont(FontKey aFontKey, ByteBuffer aBytes, uint32_t aFontIndex);
async DeleteFont(FontKey aFontKey);
async AddFontInstance(FontInstanceKey aInstanceKey, FontKey aFontKey, float aGlyphSize,
MaybeFontInstanceOptions aOptions, MaybeFontInstancePlatformOptions aPlatformOptions);
async DeleteFontInstance(FontInstanceKey aInstanceKey);
async SetDisplayList(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
LayoutSize aContentSize, ByteBuffer aDL, BuiltDisplayListDescriptor aDLDesc,
WebRenderScrollData aScrollData,
@ -71,6 +58,7 @@ parent:
WebRenderScrollData aScrollData,
ByteBuffer aResourceUpdates,
IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
async UpdateResources(ByteBuffer aResourceUpdates);
async ParentCommands(WebRenderParentCommand[] commands);
sync GetSnapshot(PTexture texture);
async AddPipelineIdForCompositable(PipelineId aImageId, CompositableHandle aHandle, bool aAsync);

View File

@ -97,6 +97,17 @@ WebRenderBridgeChild::ClearReadLocks()
mReadLocks.Clear();
}
void
WebRenderBridgeChild::UpdateResources(wr::ResourceUpdateQueue& aResources)
{
if (!IPCOpen()) {
aResources.Clear();
return;
}
wr::ByteBuffer serializedUpdates(Move(aResources.Serialize()));
this->SendUpdateResources(serializedUpdates);
}
void
WebRenderBridgeChild::EndTransaction(wr::DisplayListBuilder &aBuilder,
const gfx::IntSize& aSize,
@ -118,20 +129,18 @@ WebRenderBridgeChild::EndTransaction(wr::DisplayListBuilder &aBuilder,
fwdTime = TimeStamp::Now();
#endif
// TODO(nical)
wr::ResourceUpdateQueue updates;
wr::ByteBuffer serializedUpdates(Move(updates.Serialize()));
wr::ByteBuffer resourceUpdates(Move(aBuilder.Resources().Serialize()));
if (aIsSync) {
this->SendSetDisplayListSync(aSize, mParentCommands, mDestroyedActors,
GetFwdTransactionId(), aTransactionId,
contentSize, dlData, dl.dl_desc, aScrollData,
serializedUpdates, mIdNamespace, aTxnStartTime, fwdTime);
resourceUpdates, mIdNamespace, aTxnStartTime, fwdTime);
} else {
this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
GetFwdTransactionId(), aTransactionId,
contentSize, dlData, dl.dl_desc, aScrollData,
serializedUpdates, mIdNamespace, aTxnStartTime, fwdTime);
resourceUpdates, mIdNamespace, aTxnStartTime, fwdTime);
}
mParentCommands.Clear();
@ -263,6 +272,8 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
RefPtr<gfx::UnscaledFont> unscaled = aScaledFont->GetUnscaledFont();
MOZ_ASSERT(unscaled);
wr::ResourceUpdateQueue resources;
wr::FontKey fontKey = { wr::IdNamespace { 0 }, 0};
if (!mFontKeys.Get(unscaled, &fontKey)) {
FontFileData data;
@ -274,7 +285,7 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
fontKey.mNamespace = GetNamespace();
fontKey.mHandle = GetNextResourceId();
SendAddRawFont(fontKey, data.mFontBuffer, data.mFontIndex);
resources.AddRawFont(fontKey, data.mFontBuffer.AsSlice(), data.mFontIndex);
mFontKeys.Put(unscaled, fontKey);
}
@ -282,7 +293,8 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
instanceKey.mNamespace = GetNamespace();
instanceKey.mHandle = GetNextResourceId();
SendAddFontInstance(instanceKey, fontKey, aScaledFont->GetSize(), Nothing(), Nothing());
resources.AddFontInstance(instanceKey, fontKey, aScaledFont->GetSize(), nullptr, nullptr);
UpdateResources(resources);
mFontInstanceKeys.Put(aScaledFont, instanceKey);
@ -293,11 +305,12 @@ void
WebRenderBridgeChild::RemoveExpiredFontKeys()
{
uint32_t counter = gfx::ScaledFont::DeletionCounter();
wr::ResourceUpdateQueue resources;
if (mFontInstanceKeysDeleted != counter) {
mFontInstanceKeysDeleted = counter;
for (auto iter = mFontInstanceKeys.Iter(); !iter.Done(); iter.Next()) {
if (!iter.Key()) {
SendDeleteFontInstance(iter.Data());
resources.DeleteFontInstance(iter.Data());
iter.Remove();
}
}
@ -307,11 +320,12 @@ WebRenderBridgeChild::RemoveExpiredFontKeys()
mFontKeysDeleted = counter;
for (auto iter = mFontKeys.Iter(); !iter.Done(); iter.Next()) {
if (!iter.Key()) {
SendDeleteFont(iter.Data());
resources.DeleteFont(iter.Data());
iter.Remove();
}
}
}
UpdateResources(resources);
}
CompositorBridgeChild*

View File

@ -18,6 +18,7 @@ class CompositorWidget;
namespace wr {
class DisplayListBuilder;
class ResourceUpdateQueue;
}
namespace layers {
@ -64,11 +65,12 @@ public:
void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
void AddWebRenderParentCommands(const nsTArray<WebRenderParentCommand>& aCommands);
void UpdateResources(wr::ResourceUpdateQueue& aResources);
bool BeginTransaction(const gfx::IntSize& aSize);
void EndTransaction(wr::DisplayListBuilder &aBuilder, const gfx::IntSize& aSize,
bool aIsSync, uint64_t aTransactionId,
const WebRenderScrollData& aScrollData,
const mozilla::TimeStamp& aTxnStartTime);
bool aIsSync, uint64_t aTransactionId,
const WebRenderScrollData& aScrollData,
const mozilla::TimeStamp& aTxnStartTime);
void ProcessWebRenderParentCommands();
CompositorBridgeChild* GetCompositorBridgeChild();

View File

@ -228,175 +228,6 @@ WebRenderBridgeParent::RecvUpdateResources(const wr::ByteBuffer& aUpdates)
mApi->UpdateResources(updates);
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvAddImage(const wr::ImageKey& aImageKey,
const gfx::IntSize& aSize,
const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat,
const ByteBuffer& aBuffer)
{
if (mDestroyed) {
return IPC_OK();
}
// Check if key is obsoleted.
if (aImageKey.mNamespace != mIdNamespace) {
return IPC_OK();
}
MOZ_ASSERT(mApi);
wr::ImageDescriptor descriptor(aSize, aStride, aFormat);
mApi->Resources().AddImage(aImageKey, descriptor, aBuffer.AsSlice());
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvAddBlobImage(const wr::ImageKey& aImageKey,
const gfx::IntSize& aSize,
const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat,
const ByteBuffer& aBuffer)
{
if (mDestroyed) {
return IPC_OK();
}
// Check if key is obsoleted.
if (aImageKey.mNamespace != mIdNamespace) {
return IPC_OK();
}
MOZ_ASSERT(mApi);
wr::ImageDescriptor descriptor(aSize, aStride, aFormat);
mApi->Resources().AddBlobImage(aImageKey, descriptor, aBuffer.AsSlice());
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvAddRawFont(const wr::FontKey& aFontKey,
const ByteBuffer& aBuffer,
const uint32_t& aFontIndex)
{
if (mDestroyed) {
return IPC_OK();
}
// Check if key is obsoleted.
if (aFontKey.mNamespace != mIdNamespace) {
return IPC_OK();
}
MOZ_ASSERT(mApi);
auto slice = aBuffer.AsSlice();
mApi->Resources().AddRawFont(aFontKey, slice, aFontIndex);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvDeleteFont(const wr::FontKey& aFontKey)
{
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(mApi);
// Check if key is obsoleted.
if (aFontKey.mNamespace != mIdNamespace) {
return IPC_OK();
}
mApi->Resources().DeleteFont(aFontKey);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvAddFontInstance(const wr::FontInstanceKey& aInstanceKey,
const wr::FontKey& aFontKey,
const float& aGlyphSize,
const MaybeFontInstanceOptions& aOptions,
const MaybeFontInstancePlatformOptions& aPlatformOptions)
{
if (mDestroyed) {
return IPC_OK();
}
// Check if key is obsoleted.
if (aInstanceKey.mNamespace != mIdNamespace) {
return IPC_OK();
}
MOZ_ASSERT(mApi);
mApi->Resources().AddFontInstance(aInstanceKey, aFontKey, aGlyphSize,
aOptions.ptrOr(nullptr), aPlatformOptions.ptrOr(nullptr));
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvDeleteFontInstance(const wr::FontInstanceKey& aInstanceKey)
{
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(mApi);
// Check if key is obsoleted.
if (aInstanceKey.mNamespace != mIdNamespace) {
return IPC_OK();
}
mApi->Resources().DeleteFontInstance(aInstanceKey);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvUpdateImage(const wr::ImageKey& aImageKey,
const gfx::IntSize& aSize,
const gfx::SurfaceFormat& aFormat,
const ByteBuffer& aBuffer)
{
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(mApi);
// Check if key is obsoleted.
if (aImageKey.mNamespace != mIdNamespace) {
return IPC_OK();
}
wr::ImageDescriptor descriptor(aSize, aFormat);
mApi->Resources().UpdateImageBuffer(aImageKey, descriptor, aBuffer.AsSlice());
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvDeleteImage(const wr::ImageKey& aImageKey)
{
if (mDestroyed) {
return IPC_OK();
}
MOZ_ASSERT(mApi);
// Check if key is obsoleted.
if (aImageKey.mNamespace != mIdNamespace) {
return IPC_OK();
}
mKeysToDelete.push_back(aImageKey);
return IPC_OK();
}
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>&& aIds)
{

View File

@ -72,33 +72,8 @@ public:
mozilla::ipc::IPCResult RecvCreate(const gfx::IntSize& aSize) override;
mozilla::ipc::IPCResult RecvShutdown() override;
mozilla::ipc::IPCResult RecvShutdownSync() override;
mozilla::ipc::IPCResult RecvUpdateResources(const wr::ByteBuffer& aUpdates) override;
mozilla::ipc::IPCResult RecvAddImage(const wr::ImageKey& aImageKey,
const gfx::IntSize& aSize,
const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat,
const ByteBuffer& aBuffer) override;
mozilla::ipc::IPCResult RecvAddBlobImage(const wr::ImageKey& aImageKey,
const gfx::IntSize& aSize,
const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat,
const ByteBuffer& aBuffer) override;
mozilla::ipc::IPCResult RecvUpdateImage(const wr::ImageKey& aImageKey,
const gfx::IntSize& aSize,
const gfx::SurfaceFormat& aFormat,
const ByteBuffer& aBuffer) override;
mozilla::ipc::IPCResult RecvDeleteImage(const wr::ImageKey& a1) override;
mozilla::ipc::IPCResult RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>&& aIds) override;
mozilla::ipc::IPCResult RecvAddRawFont(const wr::FontKey& aFontKey,
const ByteBuffer& aBuffer,
const uint32_t& aFontIndex) override;
mozilla::ipc::IPCResult RecvDeleteFont(const wr::FontKey& aFontKey) override;
mozilla::ipc::IPCResult RecvAddFontInstance(const wr::FontInstanceKey& aInstanceKey,
const wr::FontKey& aFontKey,
const float& aGlyphSize,
const MaybeFontInstanceOptions& aOptions,
const MaybeFontInstancePlatformOptions& aPlatformOptions) override;
mozilla::ipc::IPCResult RecvDeleteFontInstance(const wr::FontInstanceKey& aInstanceKey) override;
mozilla::ipc::IPCResult RecvUpdateResources(const ByteBuffer& aUpdates) override;
mozilla::ipc::IPCResult RecvSetDisplayList(const gfx::IntSize& aSize,
InfallibleTArray<WebRenderParentCommand>&& aCommands,
InfallibleTArray<OpDestroy>&& aToDestroy,

View File

@ -103,7 +103,7 @@ WebRenderLayerManager::DoDestroy(bool aIsSync)
if (WrBridge()) {
// Just clear ImageKeys, they are deleted during WebRenderAPI destruction.
mImageKeysToDelete.clear();
mImageKeysToDelete.Clear();
// CompositorAnimations are cleared by WebRenderBridgeParent.
mDiscardedCompositorAnimationsIds.Clear();
WrBridge()->Destroy(aIsSync);
@ -579,9 +579,10 @@ WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
recorder->Finish();
wr::ByteBuffer bytes(recorder->mOutputStream.mLength, (uint8_t*)recorder->mOutputStream.mData);
Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
wr::ImageKey key = WrBridge()->GetNextImageKey();
WrBridge()->SendAddBlobImage(key, imageSize.ToUnknownSize(), 0, dt->GetFormat(), bytes);
wr::ImageDescriptor descriptor(imageSize.ToUnknownSize(), 0, dt->GetFormat());
aBuilder.Resources().AddBlobImage(key, descriptor, bytes);
fallbackData->SetKey(key);
} else {
fallbackData->CreateImageClientIfNeeded();
@ -909,18 +910,13 @@ WebRenderLayerManager::MakeSnapshotIfRequired(LayoutDeviceIntSize aSize)
void
WebRenderLayerManager::AddImageKeyForDiscard(wr::ImageKey key)
{
mImageKeysToDelete.push_back(key);
mImageKeysToDelete.DeleteImage(key);
}
void
WebRenderLayerManager::DiscardImages()
{
if (WrBridge()->IPCOpen()) {
for (auto key : mImageKeysToDelete) {
WrBridge()->SendDeleteImage(key);
}
}
mImageKeysToDelete.clear();
WrBridge()->UpdateResources(mImageKeysToDelete);
}
void
@ -945,7 +941,7 @@ WebRenderLayerManager::DiscardLocalImages()
// Removes images but doesn't tell the parent side about them
// This is useful in empty / failed transactions where we created
// image keys but didn't tell the parent about them yet.
mImageKeysToDelete.clear();
mImageKeysToDelete.Clear();
}
void

View File

@ -241,7 +241,7 @@ private:
private:
nsIWidget* MOZ_NON_OWNING_REF mWidget;
std::vector<wr::ImageKey> mImageKeysToDelete;
wr::ResourceUpdateQueue mImageKeysToDelete;
nsTArray<uint64_t> mDiscardedCompositorAnimationsIds;
/* PaintedLayer callbacks; valid at the end of a transaciton,

View File

@ -73,13 +73,14 @@ WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder,
wr::ByteBuffer bytes(recorder->mOutputStream.mLength, (uint8_t*)recorder->mOutputStream.mData);
//XXX: We should switch to updating the blob image instead of adding a new one
// That will get rid of this discard bit
if (mImageKey.isSome()) {
WrManager()->AddImageKeyForDiscard(mImageKey.value());
//XXX: We should switch to updating the blob image instead of adding a new one
aBuilder.Resources().DeleteImage(mImageKey.value());
}
mImageKey = Some(GenerateImageKey());
WrBridge()->SendAddBlobImage(mImageKey.value(), imageSize, 0, dt->GetFormat(), bytes);
wr::ImageDescriptor descriptor(imageSize, 0, dt->GetFormat());
aBuilder.Resources().AddBlobImage(mImageKey.value(), descriptor, bytes.AsSlice());
mImageBounds = visibleRegion.GetBounds();
}

View File

@ -482,6 +482,12 @@ ResourceUpdateQueue::Deserialize(Range<uint8_t> aData)
return result;
}
void
ResourceUpdateQueue::Clear()
{
wr_resource_updates_clear(mUpdates);
}
void
ResourceUpdateQueue::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
Range<uint8_t> aBytes)

View File

@ -110,6 +110,8 @@ public:
void DeleteFontInstance(wr::FontInstanceKey aKey);
void Clear();
// Try to avoid using this when possible.
wr::ResourceUpdates* Raw() { return mUpdates; }
@ -368,6 +370,8 @@ public:
const float& aBorderRadius,
const wr::BoxShadowClipMode& aClipMode);
ResourceUpdateQueue& Resources() { return mResourceUpdates; }
// Returns the clip id that was most recently pushed with PushClip and that
// has not yet been popped with PopClip. Return Nothing() if the clip stack
// is empty.
@ -384,6 +388,8 @@ public:
protected:
wr::WrState* mWrState;
ResourceUpdateQueue mResourceUpdates;
// Track the stack of clip ids and scroll layer ids that have been pushed
// (by PushClip and PushScrollLayer, respectively) and are still active.
// This is helpful for knowing e.g. what the ancestor scroll id of a particular

View File

@ -957,6 +957,11 @@ pub extern "C" fn wr_resource_updates_new() -> *mut ResourceUpdates {
Box::into_raw(updates)
}
#[no_mangle]
pub extern "C" fn wr_resource_updates_clear(resources: &mut ResourceUpdates) {
resources.updates.clear();
}
/// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC
#[no_mangle]
pub extern "C" fn wr_resource_updates_delete(updates: *mut ResourceUpdates) {

View File

@ -1205,6 +1205,10 @@ void wr_resource_updates_add_raw_font(ResourceUpdates *aResources,
uint32_t aIndex)
WR_FUNC;
WR_INLINE
void wr_resource_updates_clear(ResourceUpdates *aResources)
WR_FUNC;
WR_INLINE
void wr_resource_updates_delete(ResourceUpdates *aUpdates)
WR_DESTRUCTOR_SAFE_FUNC;

View File

@ -2108,13 +2108,15 @@ nsChildView::AddWindowOverlayWebRenderCommands(layers::WebRenderBridgeChild* aWr
if (!mTitlebarImageKey) {
mTitlebarImageKey = Some(aWrBridge->GetNextImageKey());
aWrBridge->SendAddImage(*mTitlebarImageKey, size, stride, format, buffer);
wr::ImageDescriptor descriptor(size, stride, format);
aBuilder.Resources().AddImage(*mTitlebarImageKey, descriptor, buffer);
mTitlebarImageSize = size;
updatedTitlebarRegion.SetEmpty();
}
if (!updatedTitlebarRegion.IsEmpty()) {
aWrBridge->SendUpdateImage(*mTitlebarImageKey, size, format, buffer);
wr::ImageDescriptor descriptor(size, stride, format);
aBuilder.Resources().UpdateImage(*mTitlebarImageKey, descriptor, buffer);
}
wr::LayoutRect rect = wr::ToLayoutRect(mTitlebarRect);
@ -2127,7 +2129,9 @@ void
nsChildView::CleanupWebRenderWindowOverlay(layers::WebRenderBridgeChild* aWrBridge)
{
if (mTitlebarImageKey) {
aWrBridge->SendDeleteImage(*mTitlebarImageKey);
ResourceUpdateQueue resources;
resources.DeleteImage(*mTitlebarImageKey);
aWrBridge->UpdateResources(resources);
mTitlebarImageKey = Nothing();
}
}