Repository: google/filament
File: filament/src/details/UboManager.cpp (C++)

Code before:

    // Actually merge the slots.
    mAllocator.releaseFreeSlots();

    // Traverse all MIs and see which of them need slot allocation.
    if (allocateOnDemand() == SUCCESS) {
        // No need to grow the buffer, so we can just map the buffer for writing and return.
        mMemoryMappedBufferHandle = driver.mapBuffer(mUbHandle, 0, mUboSize, MapBufferAccessFlags::WRITE_BIT,
                "UboManager");

        return;
    }

    // Calculate the required size and grow the Ubo.
    const allocation_size_t requiredSize = calculateRequiredSize();
    reallocate(driver, requiredSize);

    // Allocate slots for each MI on the new Ubo.
    allocateAllInstances();

    // Map the buffer so that we can write to it
    mMemoryMappedBufferHandle =
            driver.mapBuffer(mUbHandle, 0, mUboSize, MapBufferAccessFlags::WRITE_BIT, "UboManager");

    // Invalidate the migrated MIs, so that next commit() call must be triggered.
    for (const auto& mi : mManagedInstances) {
        mi->getUniformBuffer().invalidate();
    }
}

void UboManager::finishBeginFrame(DriverApi& driver) {
    if (mMemoryMappedBufferHandle) {
        driver.unmapBuffer(mMemoryMappedBufferHandle);
        mMemoryMappedBufferHandle.clear();
    }
}

void UboManager::endFrame(DriverApi& driver) {
    std::unordered_set<AllocationId> allocationIds;
    for (const auto& mi : mManagedInstances) {
        const AllocationId id = mi->getAllocationId();
        if (!BufferAllocator::isValid(id)) {
            return;
        }

        mAllocator.acquireGpu(id);
        allocationIds.insert(id);
    }

    mFenceManager.track(driver, std::move(allocationIds));
}

Review comment (performance):
this should be a `*` here not a `&` (I think you're basically getting a reference to a pointer, which is less efficient).

Code after:

    // Actually merge the slots.
    mAllocator.releaseFreeSlots();

    // Traverse all MIs and see which of them need slot allocation.
    if (allocateOnDemand() == SUCCESS) {
        // No need to grow the buffer, so we can just map the buffer for writing and return.
        mMemoryMappedBufferHandle = driver.mapBuffer(mUbHandle, 0, mUboSize, MapBufferAccessFlags::WRITE_BIT,
                "UboManager");

        return;
    }

    // Calculate the required size and grow the Ubo.
    const allocation_size_t requiredSize = calculateRequiredSize();
    reallocate(driver, requiredSize);

    // Allocate slots for each MI on the new Ubo.
    allocateAllInstances();

    // Map the buffer so that we can write to it
    mMemoryMappedBufferHandle =
            driver.mapBuffer(mUbHandle, 0, mUboSize, MapBufferAccessFlags::WRITE_BIT, "UboManager");

    // Invalidate the migrated MIs, so that next commit() call must be triggered.
    for (const auto* mi : mManagedInstances) {
        mi->getUniformBuffer().invalidate();
    }
}

void UboManager::finishBeginFrame(DriverApi& driver) {
    if (mMemoryMappedBufferHandle) {
        driver.unmapBuffer(mMemoryMappedBufferHandle);
        mMemoryMappedBufferHandle.clear();
    }
}

void UboManager::endFrame(DriverApi& driver) {
    std::unordered_set<AllocationId> allocationIds;
    for (const auto* mi : mManagedInstances) {
        const AllocationId id = mi->getAllocationId();
        if (UTILS_UNLIKELY(!BufferAllocator::isValid(id))) {
            continue;
        }

        mAllocator.acquireGpu(id);
        allocationIds.insert(id);
    }

    mFenceManager.track(driver, std::move(allocationIds));
}