Bug 1405824 - Use WebRenderBridgeChild instead of IShmemAllocator in IpcResourceUpdateQueue. r=jrmuizel

This commit is contained in:
Nicolas Silva 2018-01-12 15:11:28 +01:00
Родитель 862ff35d21
Коммит 36aaaf44e8
7 изменённых файлов: 55 добавлений и 40 удалений

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

@ -52,13 +52,13 @@ parent:
async SetDisplayList(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
LayoutSize aContentSize, ByteBuf aDL, BuiltDisplayListDescriptor aDLDesc,
WebRenderScrollData aScrollData,
OpUpdateResource[] aResourceUpdates, Shmem[] aSmallShmems, Shmem[] aLargeShmems,
OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems,
IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
async EmptyTransaction(FocusTarget focusTarget,
WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
async SetFocusTarget(FocusTarget focusTarget);
async UpdateResources(OpUpdateResource[] aResourceUpdates, Shmem[] aSmallShmems, Shmem[] aLargeShmems);
async UpdateResources(OpUpdateResource[] aResourceUpdates, RefCountedShmem[] aSmallShmems, Shmem[] aLargeShmems);
async ParentCommands(WebRenderParentCommand[] commands);
sync GetSnapshot(PTexture texture);
async AddPipelineIdForCompositable(PipelineId aImageId, CompositableHandle aHandle, bool aAsync);

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

@ -9,11 +9,14 @@
#include <algorithm>
#include "mozilla/Maybe.h"
#include "mozilla/ipc/SharedMemory.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
namespace mozilla {
namespace wr {
ShmSegmentsWriter::ShmSegmentsWriter(ipc::IShmemAllocator* aAllocator, size_t aChunkSize)
using namespace mozilla::layers;
ShmSegmentsWriter::ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize)
: mShmAllocator(aAllocator)
, mCursor(0)
, mChunkSize(aChunkSize)
@ -49,8 +52,8 @@ ShmSegmentsWriter::Write(Range<uint8_t> aBytes)
if (dstCursor >= mSmallAllocs.Length() * mChunkSize) {
if (!AllocChunk()) {
for (size_t i = mSmallAllocs.Length() ; currAllocLen < i ; i--) {
ipc::Shmem shm = mSmallAllocs.ElementAt(i);
mShmAllocator->DeallocShmem(shm);
RefCountedShmem& shm = mSmallAllocs.ElementAt(i);
RefCountedShm::Dealloc(mShmAllocator, shm);
mSmallAllocs.RemoveElementAt(i);
}
return layers::OffsetRange(0, start, 0);
@ -68,7 +71,7 @@ ShmSegmentsWriter::Write(Range<uint8_t> aBytes)
size_t copyRange = std::min<int>(availableRange, remainingBytesToCopy);
uint8_t* srcPtr = &aBytes[srcCursor];
uint8_t* dstPtr = mSmallAllocs.LastElement().get<uint8_t>() + (dstCursor - dstBaseOffset);
uint8_t* dstPtr = RefCountedShm::GetBytes(mSmallAllocs.LastElement()) + (dstCursor - dstBaseOffset);
memcpy(dstPtr, srcPtr, copyRange);
@ -88,9 +91,8 @@ ShmSegmentsWriter::Write(Range<uint8_t> aBytes)
bool
ShmSegmentsWriter::AllocChunk()
{
ipc::Shmem shm;
auto shmType = ipc::SharedMemory::SharedMemoryType::TYPE_BASIC;
if (!mShmAllocator->AllocShmem(mChunkSize, shmType, &shm)) {
RefCountedShmem shm;
if (!RefCountedShm::Alloc(mShmAllocator, mChunkSize, shm)) {
gfxCriticalNote << "ShmSegmentsWriter failed to allocate chunk #" << mSmallAllocs.Length();
MOZ_ASSERT(false, "ShmSegmentsWriter fails to allocate chunk");
return false;
@ -115,7 +117,7 @@ ShmSegmentsWriter::AllocLargeChunk(size_t aSize)
}
void
ShmSegmentsWriter::Flush(nsTArray<ipc::Shmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs)
ShmSegmentsWriter::Flush(nsTArray<RefCountedShmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs)
{
aSmallAllocs.Clear();
aLargeAllocs.Clear();
@ -128,7 +130,7 @@ ShmSegmentsWriter::Clear()
{
if (mShmAllocator) {
for (auto& shm : mSmallAllocs) {
mShmAllocator->DeallocShmem(shm);
RefCountedShm::Dealloc(mShmAllocator, shm);
}
for (auto& shm : mLargeAllocs) {
mShmAllocator->DeallocShmem(shm);
@ -139,7 +141,7 @@ ShmSegmentsWriter::Clear()
mCursor = 0;
}
ShmSegmentsReader::ShmSegmentsReader(const nsTArray<ipc::Shmem>& aSmallShmems,
ShmSegmentsReader::ShmSegmentsReader(const nsTArray<RefCountedShmem>& aSmallShmems,
const nsTArray<ipc::Shmem>& aLargeShmems)
: mSmallAllocs(aSmallShmems)
, mLargeAllocs(aLargeShmems)
@ -149,15 +151,15 @@ ShmSegmentsReader::ShmSegmentsReader(const nsTArray<ipc::Shmem>& aSmallShmems,
return;
}
mChunkSize = mSmallAllocs[0].Size<uint8_t>();
mChunkSize = RefCountedShm::GetSize(mSmallAllocs[0]);
// Check that all shmems are readable and have the same size. If anything
// isn't right, set mChunkSize to zero which signifies that the reader is
// in an invalid state and Read calls will return false;
for (const auto& shm : mSmallAllocs) {
if (!shm.IsReadable()
|| shm.Size<uint8_t>() != mChunkSize
|| shm.get<uint8_t>() == nullptr) {
if (!RefCountedShm::IsValid(shm)
|| RefCountedShm::GetSize(shm) != mChunkSize
|| RefCountedShm::GetBytes(shm) == nullptr) {
mChunkSize = 0;
return;
}
@ -219,7 +221,7 @@ ShmSegmentsReader::Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aIn
const size_t shm_idx = srcCursor / mChunkSize;
const size_t ptrOffset = srcCursor % mChunkSize;
const size_t copyRange = std::min<int>(remainingBytesToCopy, mChunkSize - ptrOffset);
uint8_t* srcPtr = mSmallAllocs[shm_idx].get<uint8_t>() + ptrOffset;
uint8_t* srcPtr = RefCountedShm::GetBytes(mSmallAllocs[shm_idx]) + ptrOffset;
aInto.PushBytes(Range<uint8_t>(srcPtr, copyRange));
@ -230,7 +232,7 @@ ShmSegmentsReader::Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aIn
return aInto.Length() - initialLength == aRange.length();
}
IpcResourceUpdateQueue::IpcResourceUpdateQueue(ipc::IShmemAllocator* aAllocator,
IpcResourceUpdateQueue::IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator,
size_t aChunkSize)
: mWriter(Move(aAllocator), aChunkSize)
{}
@ -352,7 +354,7 @@ IpcResourceUpdateQueue::DeleteFontInstance(wr::FontInstanceKey aKey)
void
IpcResourceUpdateQueue::Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
nsTArray<ipc::Shmem>& aSmallAllocs,
nsTArray<RefCountedShmem>& aSmallAllocs,
nsTArray<ipc::Shmem>& aLargeAllocs)
{
aUpdates.Clear();

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

@ -8,6 +8,7 @@
#define GFX_WR_IPCRESOURCEUPDATEQUEUE_H
#include "mozilla/layers/WebRenderMessages.h"
#include "mozilla/layers/RefCountedShmem.h"
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
@ -20,7 +21,7 @@ namespace wr {
/// allocations and creates dedicated shmems for large allocations.
class ShmSegmentsWriter {
public:
ShmSegmentsWriter(ipc::IShmemAllocator* aAllocator, size_t aChunkSize);
ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize);
~ShmSegmentsWriter();
layers::OffsetRange Write(Range<uint8_t> aBytes);
@ -31,7 +32,7 @@ public:
return Write(Range<uint8_t>((uint8_t*)aValues.begin().get(), aValues.length() * sizeof(T)));
}
void Flush(nsTArray<ipc::Shmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs);
void Flush(nsTArray<layers::RefCountedShmem>& aSmallAllocs, nsTArray<ipc::Shmem>& aLargeAllocs);
void Clear();
@ -39,16 +40,16 @@ protected:
bool AllocChunk();
layers::OffsetRange AllocLargeChunk(size_t aSize);
nsTArray<ipc::Shmem> mSmallAllocs;
nsTArray<layers::RefCountedShmem> mSmallAllocs;
nsTArray<ipc::Shmem> mLargeAllocs;
ipc::IShmemAllocator* mShmAllocator;
layers::WebRenderBridgeChild* mShmAllocator;
size_t mCursor;
size_t mChunkSize;
};
class ShmSegmentsReader {
public:
ShmSegmentsReader(const nsTArray<ipc::Shmem>& aSmallShmems,
ShmSegmentsReader(const nsTArray<layers::RefCountedShmem>& aSmallShmems,
const nsTArray<ipc::Shmem>& aLargeShmems);
bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
@ -56,7 +57,7 @@ public:
protected:
bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
const nsTArray<ipc::Shmem>& mSmallAllocs;
const nsTArray<layers::RefCountedShmem>& mSmallAllocs;
const nsTArray<ipc::Shmem>& mLargeAllocs;
size_t mChunkSize;
};
@ -67,7 +68,7 @@ public:
// Each shmem has two guard pages, and the minimum shmem size (at least one Windows)
// is 64k which is already quite large for a lot of the resources we use here.
// So we pick 64k - 2 * 4k = 57344 bytes as the defautl alloc
explicit IpcResourceUpdateQueue(ipc::IShmemAllocator* aAllocator, size_t aChunkSize = 57344);
explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize = 57344);
bool AddImage(wr::ImageKey aKey,
const ImageDescriptor& aDescriptor,
@ -114,7 +115,7 @@ public:
void Clear();
void Flush(nsTArray<layers::OpUpdateResource>& aUpdates,
nsTArray<ipc::Shmem>& aSmallAllocs,
nsTArray<layers::RefCountedShmem>& aSmallAllocs,
nsTArray<ipc::Shmem>& aLargeAllocs);
protected:

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

@ -125,7 +125,7 @@ WebRenderBridgeChild::UpdateResources(wr::IpcResourceUpdateQueue& aResources)
}
nsTArray<OpUpdateResource> resourceUpdates;
nsTArray<ipc::Shmem> smallShmems;
nsTArray<RefCountedShmem> smallShmems;
nsTArray<ipc::Shmem> largeShmems;
aResources.Flush(resourceUpdates, smallShmems, largeShmems);
@ -154,7 +154,7 @@ WebRenderBridgeChild::EndTransaction(const wr::LayoutSize& aContentSize,
#endif
nsTArray<OpUpdateResource> resourceUpdates;
nsTArray<ipc::Shmem> smallShmems;
nsTArray<RefCountedShmem> smallShmems;
nsTArray<ipc::Shmem> largeShmems;
aResources.Flush(resourceUpdates, smallShmems, largeShmems);
@ -321,7 +321,7 @@ WebRenderBridgeChild::GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont)
return instanceKey;
}
wr::IpcResourceUpdateQueue resources(GetShmemAllocator());
wr::IpcResourceUpdateQueue resources(this);
wr::FontKey fontKey = GetFontKeyForUnscaledFont(aScaledFont->GetUnscaledFont());
wr::FontKey nullKey = { wr::IdNamespace { 0 }, 0};
@ -354,7 +354,7 @@ WebRenderBridgeChild::GetFontKeyForUnscaledFont(gfx::UnscaledFont* aUnscaled)
wr::FontKey fontKey = { wr::IdNamespace { 0 }, 0};
if (!mFontKeys.Get(aUnscaled, &fontKey)) {
wr::IpcResourceUpdateQueue resources(GetShmemAllocator());
wr::IpcResourceUpdateQueue resources(this);
FontFileDataSink sink = { &fontKey, this, &resources };
// First try to retrieve a descriptor for the font, as this is much cheaper
// to send over IPC than the full raw font data. If this is not possible, then
@ -376,7 +376,7 @@ void
WebRenderBridgeChild::RemoveExpiredFontKeys()
{
uint32_t counter = gfx::ScaledFont::DeletionCounter();
wr::IpcResourceUpdateQueue resources(GetShmemAllocator());
wr::IpcResourceUpdateQueue resources(this);
if (mFontInstanceKeysDeleted != counter) {
mFontInstanceKeysDeleted = counter;
for (auto iter = mFontInstanceKeys.Iter(); !iter.Done(); iter.Next()) {

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

@ -277,9 +277,20 @@ WebRenderBridgeParent::DeallocShmems(nsTArray<ipc::Shmem>& aShmems)
aShmems.Clear();
}
void
WebRenderBridgeParent::DeallocShmems(nsTArray<RefCountedShmem>& aShmems)
{
if (IPCOpen()) {
for (auto& shm : aShmems) {
RefCountedShm::Dealloc(this, shm);
}
}
aShmems.Clear();
}
bool
WebRenderBridgeParent::UpdateResources(const nsTArray<OpUpdateResource>& aResourceUpdates,
const nsTArray<ipc::Shmem>& aSmallShmems,
const nsTArray<RefCountedShmem>& aSmallShmems,
const nsTArray<ipc::Shmem>& aLargeShmems,
wr::ResourceUpdateQueue& aUpdates)
{
@ -450,7 +461,7 @@ WebRenderBridgeParent::AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey
mozilla::ipc::IPCResult
WebRenderBridgeParent::RecvUpdateResources(nsTArray<OpUpdateResource>&& aResourceUpdates,
nsTArray<ipc::Shmem>&& aSmallShmems,
nsTArray<RefCountedShmem>&& aSmallShmems,
nsTArray<ipc::Shmem>&& aLargeShmems)
{
if (mDestroyed) {
@ -580,7 +591,7 @@ WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
const wr::BuiltDisplayListDescriptor& dlDesc,
const WebRenderScrollData& aScrollData,
nsTArray<OpUpdateResource>&& aResourceUpdates,
nsTArray<ipc::Shmem>&& aSmallShmems,
nsTArray<RefCountedShmem>&& aSmallShmems,
nsTArray<ipc::Shmem>&& aLargeShmems,
const wr::IdNamespace& aIdNamespace,
const TimeStamp& aTxnStartTime,

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

@ -74,7 +74,7 @@ public:
mozilla::ipc::IPCResult RecvShutdownSync() override;
mozilla::ipc::IPCResult RecvDeleteCompositorAnimations(InfallibleTArray<uint64_t>&& aIds) override;
mozilla::ipc::IPCResult RecvUpdateResources(nsTArray<OpUpdateResource>&& aUpdates,
nsTArray<ipc::Shmem>&& aSmallShmems,
nsTArray<RefCountedShmem>&& aSmallShmems,
nsTArray<ipc::Shmem>&& aLargeShmems) override;
mozilla::ipc::IPCResult RecvSetDisplayList(const gfx::IntSize& aSize,
InfallibleTArray<WebRenderParentCommand>&& aCommands,
@ -86,7 +86,7 @@ public:
const wr::BuiltDisplayListDescriptor& dlDesc,
const WebRenderScrollData& aScrollData,
nsTArray<OpUpdateResource>&& aResourceUpdates,
nsTArray<ipc::Shmem>&& aSmallShmems,
nsTArray<RefCountedShmem>&& aSmallShmems,
nsTArray<ipc::Shmem>&& aLargeShmems,
const wr::IdNamespace& aIdNamespace,
const TimeStamp& aTxnStartTime,
@ -193,12 +193,13 @@ public:
private:
void DeallocShmems(nsTArray<ipc::Shmem>& aShmems);
void DeallocShmems(nsTArray<RefCountedShmem>& aShmems);
explicit WebRenderBridgeParent(const wr::PipelineId& aPipelineId);
virtual ~WebRenderBridgeParent();
bool UpdateResources(const nsTArray<OpUpdateResource>& aResourceUpdates,
const nsTArray<ipc::Shmem>& aSmallShmems,
const nsTArray<RefCountedShmem>& aSmallShmems,
const nsTArray<ipc::Shmem>& aLargeShmems,
wr::ResourceUpdateQueue& aUpdates);
bool AddExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey,

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

@ -267,7 +267,7 @@ WebRenderLayerManager::EndTransactionWithoutLayer(nsDisplayList* aDisplayList,
LayoutDeviceIntSize size = mWidget->GetClientSize();
wr::LayoutSize contentSize { (float)size.width, (float)size.height };
wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize, mLastDisplayListSize);
wr::IpcResourceUpdateQueue resourceUpdates(WrBridge()->GetShmemAllocator());
wr::IpcResourceUpdateQueue resourceUpdates(WrBridge());
mWebRenderCommandBuilder.BuildWebRenderCommands(builder,
resourceUpdates,
@ -413,7 +413,7 @@ WebRenderLayerManager::AddImageKeyForDiscard(wr::ImageKey key)
void
WebRenderLayerManager::DiscardImages()
{
wr::IpcResourceUpdateQueue resources(WrBridge()->GetShmemAllocator());
wr::IpcResourceUpdateQueue resources(WrBridge());
for (const auto& key : mImageKeysToDeleteLater) {
resources.DeleteImage(key);
}