mirror of
https://github.com/PabloMK7/citra.git
synced 2025-10-11 20:10:03 +00:00
Implement app management support (suspend, resume, close, etc) (#6322)
This commit is contained in:
parent
d2caf2d386
commit
c96f54f022
21 changed files with 1043 additions and 110 deletions
|
@ -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"},
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue