From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- gfx/layers/wr/IpcResourceUpdateQueue.h | 195 +++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 gfx/layers/wr/IpcResourceUpdateQueue.h (limited to 'gfx/layers/wr/IpcResourceUpdateQueue.h') diff --git a/gfx/layers/wr/IpcResourceUpdateQueue.h b/gfx/layers/wr/IpcResourceUpdateQueue.h new file mode 100644 index 0000000000..6096ddbddb --- /dev/null +++ b/gfx/layers/wr/IpcResourceUpdateQueue.h @@ -0,0 +1,195 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GFX_WR_IPCRESOURCEUPDATEQUEUE_H +#define GFX_WR_IPCRESOURCEUPDATEQUEUE_H + +#include "mozilla/layers/WebRenderMessages.h" +#include "mozilla/layers/RefCountedShmem.h" +#include "mozilla/layers/TextureClient.h" +#include "mozilla/webrender/WebRenderTypes.h" + +namespace mozilla { +namespace ipc { +class IShmemAllocator; +} +namespace layers { +class TextureClient; +class WebRenderBridgeChild; +} // namespace layers + +namespace wr { + +/// ShmSegmentsWriter pushes bytes in a sequence of fixed size shmems for small +/// allocations and creates dedicated shmems for large allocations. +class ShmSegmentsWriter { + public: + ShmSegmentsWriter(layers::WebRenderBridgeChild* aAllocator, + size_t aChunkSize); + ~ShmSegmentsWriter(); + + ShmSegmentsWriter(ShmSegmentsWriter&& aOther) noexcept; + ShmSegmentsWriter& operator=(ShmSegmentsWriter&& aOther) noexcept; + + ShmSegmentsWriter(const ShmSegmentsWriter& aOther) = delete; + ShmSegmentsWriter& operator=(const ShmSegmentsWriter& aOther) = delete; + + layers::OffsetRange Write(Range aBytes); + + template + layers::OffsetRange WriteAsBytes(Range aValues) { + return Write(Range((uint8_t*)aValues.begin().get(), + aValues.length() * sizeof(T))); + } + + void Flush(nsTArray& aSmallAllocs, + nsTArray& aLargeAllocs); + + void Clear(); + bool IsEmpty() const; + + layers::WebRenderBridgeChild* WrBridge() const { return mShmAllocator; } + size_t ChunkSize() const { return mChunkSize; } + + protected: + bool AllocChunk(); + layers::OffsetRange AllocLargeChunk(size_t aSize); + + nsTArray mSmallAllocs; + nsTArray mLargeAllocs; + layers::WebRenderBridgeChild* mShmAllocator; + size_t mCursor; + size_t mChunkSize; +}; + +class ShmSegmentsReader { + public: + ShmSegmentsReader(const nsTArray& aSmallShmems, + const nsTArray& aLargeShmems); + + bool Read(const layers::OffsetRange& aRange, wr::Vec& aInto); + + // Get a read pointer, if possible, directly into the shm. If the range has + // been broken up into multiple chunks that can't be represented by a single + // range, nothing will be returned to indicate failure. + Maybe> GetReadPointer(const layers::OffsetRange& aRange); + + // Get a read pointer, if possible, directly into the shm. Otherwise, copy + // it into the Vec and return a pointer to that contiguous memory instead. + // If all fails, return nothing. + Maybe> GetReadPointerOrCopy(const layers::OffsetRange& aRange, + wr::Vec& aInto) { + if (Maybe> ptr = GetReadPointer(aRange)) { + return ptr; + } else { + size_t initialLength = aInto.Length(); + if (Read(aRange, aInto)) { + return Some(Range(aInto.Data() + initialLength, + aInto.Length() - initialLength)); + } else { + return Nothing(); + } + } + } + + protected: + bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec& aInto); + + Maybe> GetReadPointerLarge(const layers::OffsetRange& aRange); + + const nsTArray& mSmallAllocs; + const nsTArray& mLargeAllocs; + size_t mChunkSize; +}; + +class IpcResourceUpdateQueue { + public: + // Because we are using shmems, the size should be a multiple of the page + // size. 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. The RefCountedShmem type used to allocate the chunks keeps a + // 16 bytes header in the buffer which we account for here as well. So we pick + // 64k - 2 * 4k - 16 = 57328 bytes as the default alloc size. + explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator, + size_t aChunkSize = 57328); + + IpcResourceUpdateQueue(IpcResourceUpdateQueue&& aOther) noexcept; + IpcResourceUpdateQueue& operator=(IpcResourceUpdateQueue&& aOther) noexcept; + + IpcResourceUpdateQueue(const IpcResourceUpdateQueue& aOther) = delete; + IpcResourceUpdateQueue& operator=(const IpcResourceUpdateQueue& aOther) = + delete; + + // Moves over everything but the subqueues + void ReplaceResources(IpcResourceUpdateQueue&& aOther); + + bool AddImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor, + Range aBytes); + + bool AddBlobImage(wr::BlobImageKey aKey, const ImageDescriptor& aDescriptor, + Range aBytes, ImageIntRect aVisibleRect); + + void AddSharedExternalImage(wr::ExternalImageId aExtId, wr::ImageKey aKey); + + void PushExternalImageForTexture(wr::ExternalImageId aExtId, + wr::ImageKey aKey, + layers::TextureClient* aTexture, + bool aIsUpdate); + + bool UpdateImageBuffer(wr::ImageKey aKey, const ImageDescriptor& aDescriptor, + Range aBytes); + + bool UpdateBlobImage(wr::BlobImageKey aKey, + const ImageDescriptor& aDescriptor, + Range aBytes, ImageIntRect aVisibleRect, + ImageIntRect aDirtyRect); + + void UpdateSharedExternalImage(ExternalImageId aExtID, ImageKey aKey, + ImageIntRect aDirtyRect); + + void SetBlobImageVisibleArea(BlobImageKey aKey, const ImageIntRect& aArea); + + void DeleteImage(wr::ImageKey aKey); + + void DeleteBlobImage(wr::BlobImageKey aKey); + + bool AddRawFont(wr::FontKey aKey, Range aBytes, uint32_t aIndex); + + bool AddFontDescriptor(wr::FontKey aKey, Range aBytes, + uint32_t aIndex); + + void DeleteFont(wr::FontKey aKey); + + void AddFontInstance(wr::FontInstanceKey aKey, wr::FontKey aFontKey, + float aGlyphSize, + const wr::FontInstanceOptions* aOptions, + const wr::FontInstancePlatformOptions* aPlatformOptions, + Range aVariations); + + void DeleteFontInstance(wr::FontInstanceKey aKey); + + void Clear(); + + void Flush(nsTArray& aUpdates, + nsTArray& aSmallAllocs, + nsTArray& aLargeAllocs); + + bool IsEmpty() const; + + static void ReleaseShmems(mozilla::ipc::IProtocol*, + nsTArray& aShms); + static void ReleaseShmems(mozilla::ipc::IProtocol*, + nsTArray& aShms); + + protected: + ShmSegmentsWriter mWriter; + nsTArray mUpdates; +}; + +} // namespace wr +} // namespace mozilla + +#endif -- cgit v1.2.3