Implement app management support (suspend, resume, close, etc) (#6322)

This commit is contained in:
Steveice10 2023-03-09 15:44:26 -08:00 committed by GitHub
parent d2caf2d386
commit c96f54f022
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1043 additions and 110 deletions

View file

@ -663,14 +663,17 @@ void GSP_GPU::TriggerCmdReqQueue(Kernel::HLERequestContext& ctx) {
void GSP_GPU::ImportDisplayCaptureInfo(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x18, 0, 0);
// TODO(Subv): We're always returning the framebuffer structures for thread_id = 0,
// because we only support a single running application at a time.
// This should always return the framebuffer data that is currently displayed on the screen.
if (active_thread_id == UINT32_MAX) {
LOG_WARNING(Service_GSP, "Called without an active thread.");
u32 thread_id = 0;
// TODO: Find the right error code.
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(-1);
return;
}
FrameBufferUpdate* top_screen = GetFrameBufferInfo(thread_id, 0);
FrameBufferUpdate* bottom_screen = GetFrameBufferInfo(thread_id, 1);
FrameBufferUpdate* top_screen = GetFrameBufferInfo(active_thread_id, 0);
FrameBufferUpdate* bottom_screen = GetFrameBufferInfo(active_thread_id, 1);
struct CaptureInfoEntry {
u32_le address_left;
@ -700,6 +703,39 @@ void GSP_GPU::ImportDisplayCaptureInfo(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_GSP, "called");
}
void GSP_GPU::SaveVramSysArea(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x19, 0, 0);
LOG_INFO(Service_GSP, "called");
// TODO: This should also DMA framebuffers into VRAM and save LCD register state.
Memory::RasterizerFlushVirtualRegion(Memory::VRAM_VADDR, Memory::VRAM_SIZE,
Memory::FlushMode::Flush);
auto vram = system.Memory().GetPointer(Memory::VRAM_VADDR);
saved_vram.emplace(std::vector<u8>(Memory::VRAM_SIZE));
std::memcpy(saved_vram.get().data(), vram, Memory::VRAM_SIZE);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
}
void GSP_GPU::RestoreVramSysArea(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1A, 0, 0);
LOG_INFO(Service_GSP, "called");
if (saved_vram) {
// TODO: This should also restore LCD register state.
auto vram = system.Memory().GetPointer(Memory::VRAM_VADDR);
std::memcpy(vram, saved_vram.get().data(), Memory::VRAM_SIZE);
Memory::RasterizerFlushVirtualRegion(Memory::VRAM_VADDR, Memory::VRAM_SIZE,
Memory::FlushMode::Invalidate);
}
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
}
void GSP_GPU::AcquireRight(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x16, 1, 2);
@ -808,8 +844,8 @@ GSP_GPU::GSP_GPU(Core::System& system) : ServiceFramework("gsp::Gpu", 2), system
{0x00160042, &GSP_GPU::AcquireRight, "AcquireRight"},
{0x00170000, &GSP_GPU::ReleaseRight, "ReleaseRight"},
{0x00180000, &GSP_GPU::ImportDisplayCaptureInfo, "ImportDisplayCaptureInfo"},
{0x00190000, nullptr, "SaveVramSysArea"},
{0x001A0000, nullptr, "RestoreVramSysArea"},
{0x00190000, &GSP_GPU::SaveVramSysArea, "SaveVramSysArea"},
{0x001A0000, &GSP_GPU::RestoreVramSysArea, "RestoreVramSysArea"},
{0x001B0000, nullptr, "ResetGpuCore"},
{0x001C0040, &GSP_GPU::SetLedForceOff, "SetLedForceOff"},
{0x001D0040, nullptr, "SetTestCommand"},

View file

@ -8,6 +8,7 @@
#include <memory>
#include <string>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/optional.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include "common/bit_field.h"
#include "common/common_types.h"
@ -238,6 +239,13 @@ public:
*/
FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index);
/**
* Retreives the ID of the thread with GPU rights.
*/
u32 GetActiveThreadId() {
return active_thread_id;
}
private:
/**
* Signals that the specified interrupt type has occurred to userland code for the specified GSP
@ -402,6 +410,32 @@ private:
*/
void ImportDisplayCaptureInfo(Kernel::HLERequestContext& ctx);
/**
* GSP_GPU::SaveVramSysArea service function
*
* Returns information about the current framebuffer state
*
* Inputs:
* 0: Header 0x00190000
* Outputs:
* 0: Header Code[0x00190040]
* 1: Result code
*/
void SaveVramSysArea(Kernel::HLERequestContext& ctx);
/**
* GSP_GPU::RestoreVramSysArea service function
*
* Returns information about the current framebuffer state
*
* Inputs:
* 0: Header 0x001A0000
* Outputs:
* 0: Header Code[0x001A0040]
* 1: Result code
*/
void RestoreVramSysArea(Kernel::HLERequestContext& ctx);
/**
* GSP_GPU::StoreDataCache service function
*
@ -438,6 +472,9 @@ private:
bool first_initialization = true;
/// VRAM copy saved using SaveVramSysArea.
boost::optional<std::vector<u8>> saved_vram;
/// Maximum number of threads that can be registered at the same time in the GSP module.
static constexpr u32 MaxGSPThreads = 4;
@ -453,6 +490,7 @@ private:
ar& active_thread_id;
ar& first_initialization;
ar& used_thread_ids;
ar& saved_vram;
}
friend class boost::serialization::access;