Bug 1872705: Set a maximum number of recycled canvas buffers. r=gfx-reviewers,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D197856
This commit is contained in:
Bob Owen 2024-01-10 08:19:03 +00:00
Родитель 6d6b682a26
Коммит 9576894912
4 изменённых файлов: 35 добавлений и 3 удалений

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

@ -37,6 +37,7 @@ static Maybe<ShmemAndHandle> CreateAndMapShmem(size_t aSize) {
CanvasDrawEventRecorder::CanvasDrawEventRecorder() {
mDefaultBufferSize = ipc::SharedMemory::PageAlignedSize(
StaticPrefs::gfx_canvas_remote_default_buffer_size());
mMaxDefaultBuffers = StaticPrefs::gfx_canvas_remote_max_default_buffers();
mMaxSpinCount = StaticPrefs::gfx_canvas_remote_max_spin_count();
mDropBufferLimit = StaticPrefs::gfx_canvas_remote_drop_buffer_limit();
mDropBufferOnZero = mDropBufferLimit;
@ -176,9 +177,25 @@ gfx::ContiguousBuffer& CanvasDrawEventRecorder::GetContiguousBuffer(
return mCurrentBuffer;
}
// If the next recycled buffer is big enough and free use that.
if (mRecycledBuffers.front().Capacity() > aSize &&
mRecycledBuffers.front().eventCount <= mHeader->processedCount) {
bool useRecycledBuffer = false;
if (mRecycledBuffers.front().Capacity() > aSize) {
// The recycled buffer is big enough, check if it is free.
if (mRecycledBuffers.front().eventCount <= mHeader->processedCount) {
useRecycledBuffer = true;
} else if (mRecycledBuffers.size() >= mMaxDefaultBuffers) {
// We've hit he max number of buffers, wait for the next one to be free.
// We wait for (eventCount - 1), as we check and signal in the translator
// during the play event, before the processedCount has been updated.
useRecycledBuffer = true;
if (!WaitForCheckpoint(mRecycledBuffers.front().eventCount - 1)) {
// The wait failed or we're shutting down, just return an empty buffer.
mCurrentBuffer = CanvasBuffer();
return mCurrentBuffer;
}
}
}
if (useRecycledBuffer) {
// Only queue default size buffers for recycling.
if (mCurrentBuffer.Capacity() == mDefaultBufferSize) {
WriteInternalEvent(RECYCLE_BUFFER);

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

@ -129,6 +129,7 @@ class CanvasDrawEventRecorder final : public gfx::DrawEventRecorderPrivate,
void CheckAndSignalReader();
size_t mDefaultBufferSize;
size_t mMaxDefaultBuffers;
uint32_t mMaxSpinCount;
uint32_t mDropBufferLimit;
uint32_t mDropBufferOnZero;

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

@ -227,6 +227,10 @@ void CanvasTranslator::AddBuffer(ipc::SharedMemoryBasic::Handle&& aBufferHandle,
MOZ_RELEASE_ASSERT(mHeader->readerState == State::Paused);
MOZ_ASSERT(mDefaultBufferSize != 0);
// Check and signal the writer when we finish with a buffer, because it
// might have hit the buffer count limit and be waiting to use our old one.
CheckAndSignalWriter();
// Default sized buffers will have been queued for recycling.
if (mCurrentShmem.Size() == mDefaultBufferSize) {
mCanvasShmems.emplace(std::move(mCurrentShmem));
@ -326,6 +330,10 @@ void CanvasTranslator::RecycleBuffer() {
}
void CanvasTranslator::NextBuffer() {
// Check and signal the writer when we finish with a buffer, because it
// might have hit the buffer count limit and be waiting to use our old one.
CheckAndSignalWriter();
mCurrentShmem = std::move(mCanvasShmems.front());
mCanvasShmems.pop();
mCurrentMemReader = mCurrentShmem.CreateMemReader();

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

@ -5741,6 +5741,12 @@
value: 32 * 1024
mirror: always
# Maximum number of Default size shmem buffers to use
- name: gfx.canvas.remote.max_default_buffers
type: RelaxedAtomicUint32
value: 256
mirror: always
# How many times to spin before waiting in remote canvas
- name: gfx.canvas.remote.max-spin-count
type: RelaxedAtomicUint32