summaryrefslogblamecommitdiffstats
path: root/src/audio_core/renderer/system_manager.cpp
blob: a0b8ef29e141263ab927549fe3660a8bb01d18f5 (plain) (tree)
1
2
3
4
5
6
7




                                                               
                                 
                                  








                                                                                
                               

                                                 
                                                                             




                                 
                                        
                  


                                                                                              
     





                            
                   
                          
                  
                          












                                                                                           
                               
























                                                                                         
                                                            
                                                             


                                                                   
                                                    









                                                          

                                


     
                                  
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include <chrono>

#include "audio_core/adsp/adsp.h"
#include "audio_core/audio_core.h"
#include "audio_core/renderer/system_manager.h"
#include "common/microprofile.h"
#include "common/thread.h"
#include "core/core.h"
#include "core/core_timing.h"

MICROPROFILE_DEFINE(Audio_RenderSystemManager, "Audio", "Render System Manager",
                    MP_RGB(60, 19, 97));

namespace AudioCore::Renderer {

SystemManager::SystemManager(Core::System& core_)
    : core{core_}, audio_renderer{core.AudioCore().ADSP().AudioRenderer()} {}

SystemManager::~SystemManager() {
    Stop();
}

void SystemManager::InitializeUnsafe() {
    if (!active) {
        active = true;
        audio_renderer.Start();
        thread = std::jthread([this](std::stop_token stop_token) { ThreadFunc(stop_token); });
    }
}

void SystemManager::Stop() {
    if (!active) {
        return;
    }
    active = false;
    thread.request_stop();
    thread.join();
    audio_renderer.Stop();
}

bool SystemManager::Add(System& system_) {
    std::scoped_lock l2{mutex2};

    if (systems.size() + 1 > MaxRendererSessions) {
        LOG_ERROR(Service_Audio, "Maximum AudioRenderer Systems active, cannot add more!");
        return false;
    }

    {
        std::scoped_lock l{mutex1};
        if (systems.empty()) {
            InitializeUnsafe();
        }
    }

    systems.push_back(&system_);
    return true;
}

bool SystemManager::Remove(System& system_) {
    std::scoped_lock l2{mutex2};

    {
        std::scoped_lock l{mutex1};
        if (systems.remove(&system_) == 0) {
            LOG_ERROR(Service_Audio,
                      "Failed to remove a render system, it was not found in the list!");
            return false;
        }
    }

    if (systems.empty()) {
        Stop();
    }
    return true;
}

void SystemManager::ThreadFunc(std::stop_token stop_token) {
    static constexpr char name[]{"AudioRenderSystemManager"};
    MicroProfileOnThreadCreate(name);
    Common::SetCurrentThreadName(name);
    Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
    while (active && !stop_token.stop_requested()) {
        {
            std::scoped_lock l{mutex1};

            MICROPROFILE_SCOPE(Audio_RenderSystemManager);

            for (auto system : systems) {
                system->SendCommandToDsp();
            }
        }

        audio_renderer.Signal();
        audio_renderer.Wait();
    }
}

} // namespace AudioCore::Renderer