/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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/. */ #include "WebGLChild.h" #include "ClientWebGLContext.h" #include "mozilla/StaticPrefs_webgl.h" #include "WebGLMethodDispatcher.h" namespace mozilla::dom { WebGLChild::WebGLChild(ClientWebGLContext& context) : mContext(&context), mDefaultCmdsShmemSize(StaticPrefs::webgl_out_of_process_shmem_size()) {} WebGLChild::~WebGLChild() { (void)Send__delete__(this); } void WebGLChild::ActorDestroy(ActorDestroyReason why) { mPendingCmdsShmem = {}; } // - Maybe> WebGLChild::AllocPendingCmdBytes( const size_t size, const size_t fyiAlignmentOverhead) { if (!mPendingCmdsShmem.Size()) { size_t capacity = mDefaultCmdsShmemSize; if (capacity < size) { capacity = size; } mPendingCmdsShmem = mozilla::ipc::BigBuffer::TryAlloc(capacity); if (!mPendingCmdsShmem.Size()) { NS_WARNING("Failed to alloc shmem for AllocPendingCmdBytes."); return {}; } mPendingCmdsPos = 0; mPendingCmdsAlignmentOverhead = 0; if (kIsDebug) { const auto ptr = mPendingCmdsShmem.Data(); const auto initialOffset = AlignmentOffset(kUniversalAlignment, ptr); MOZ_ALWAYS_TRUE(!initialOffset); } } const auto range = Range{mPendingCmdsShmem.AsSpan()}; auto itr = range.begin() + mPendingCmdsPos; const auto offset = AlignmentOffset(kUniversalAlignment, itr.get()); mPendingCmdsPos += offset; mPendingCmdsAlignmentOverhead += offset; const auto required = mPendingCmdsPos + size; if (required > range.length()) { FlushPendingCmds(); return AllocPendingCmdBytes(size, fyiAlignmentOverhead); } itr = range.begin() + mPendingCmdsPos; const auto remaining = Range{itr, range.end()}; mPendingCmdsPos += size; mPendingCmdsAlignmentOverhead += fyiAlignmentOverhead; return Some(Range{remaining.begin(), remaining.begin() + size}); } void WebGLChild::FlushPendingCmds() { if (!mPendingCmdsShmem.Size()) return; const auto byteSize = mPendingCmdsPos; SendDispatchCommands(std::move(mPendingCmdsShmem), byteSize); mPendingCmdsShmem = {}; mFlushedCmdInfo.flushes += 1; mFlushedCmdInfo.flushedCmdBytes += byteSize; mFlushedCmdInfo.overhead += mPendingCmdsAlignmentOverhead; if (gl::GLContext::ShouldSpew()) { const auto overheadRatio = float(mPendingCmdsAlignmentOverhead) / (byteSize - mPendingCmdsAlignmentOverhead); const auto totalOverheadRatio = float(mFlushedCmdInfo.overhead) / (mFlushedCmdInfo.flushedCmdBytes - mFlushedCmdInfo.overhead); printf_stderr( "[WebGLChild] Flushed %zu (%zu=%.2f%% overhead) bytes." " (%zu (%.2f%% overhead) over %zu flushes)\n", byteSize, mPendingCmdsAlignmentOverhead, 100 * overheadRatio, mFlushedCmdInfo.flushedCmdBytes, 100 * totalOverheadRatio, mFlushedCmdInfo.flushes); } } // - mozilla::ipc::IPCResult WebGLChild::RecvJsWarning( const std::string& text) const { if (!mContext) return IPC_OK(); mContext->JsWarning(text); return IPC_OK(); } mozilla::ipc::IPCResult WebGLChild::RecvOnContextLoss( const webgl::ContextLossReason reason) const { if (!mContext) return IPC_OK(); mContext->OnContextLoss(reason); return IPC_OK(); } } // namespace mozilla::dom