mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-11-15 09:36:35 +00:00
fatal: update screen task to use native window directly
This commit is contained in:
parent
ea9d360b14
commit
2696240566
1 changed files with 62 additions and 39 deletions
|
@ -48,28 +48,9 @@ namespace ams::fatal::srv {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void *__libnx_tmem_alloc(size_t size) {
|
extern "C" ::Result __nx_nv_create_tmem(TransferMemory *t, u32 *out_size, Permission perm) {
|
||||||
return ams::fatal::srv::g_nv_transfer_memory;
|
*out_size = sizeof(ams::fatal::srv::g_nv_transfer_memory);
|
||||||
}
|
return tmemCreateFromMemory(t, ams::fatal::srv::g_nv_transfer_memory, sizeof(ams::fatal::srv::g_nv_transfer_memory), perm);
|
||||||
|
|
||||||
extern "C" void __libnx_tmem_free(void *mem) {
|
|
||||||
/* ... */
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void *__libnx_framebuffer_alloc(size_t size) {
|
|
||||||
return ams::fatal::srv::g_framebuffer_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void __libnx_framebuffer_free(void *mem) {
|
|
||||||
/* ... */
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void *__libnx_framebuffer_linear_alloc(size_t size) {
|
|
||||||
AMS_ABORT("__libnx_framebuffer_linear_alloc was called");
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void __libnx_framebuffer_linear_free(void *mem) {
|
|
||||||
AMS_ABORT("__libnx_framebuffer_linear_free was called");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ams::fatal::srv {
|
namespace ams::fatal::srv {
|
||||||
|
@ -92,12 +73,14 @@ namespace ams::fatal::srv {
|
||||||
ViDisplay display;
|
ViDisplay display;
|
||||||
ViLayer layer;
|
ViLayer layer;
|
||||||
NWindow win;
|
NWindow win;
|
||||||
Framebuffer fb;
|
NvMap map;
|
||||||
private:
|
private:
|
||||||
Result SetupDisplayInternal();
|
Result SetupDisplayInternal();
|
||||||
Result SetupDisplayExternal();
|
Result SetupDisplayExternal();
|
||||||
Result PrepareScreenForDrawing();
|
Result PrepareScreenForDrawing();
|
||||||
void PreRenderFrameBuffer();
|
void PreRenderFrameBuffer();
|
||||||
|
Result InitializeNativeWindow();
|
||||||
|
void DisplayPreRenderedFrame();
|
||||||
Result ShowFatal();
|
Result ShowFatal();
|
||||||
public:
|
public:
|
||||||
virtual Result Run() override;
|
virtual Result Run() override;
|
||||||
|
@ -192,15 +175,15 @@ namespace ams::fatal::srv {
|
||||||
/* Display a layer of 1280 x 720 at 1.5x magnification */
|
/* Display a layer of 1280 x 720 at 1.5x magnification */
|
||||||
/* NOTE: N uses 2 (770x400) RGBA4444 buffers (tiled buffer + linear). */
|
/* NOTE: N uses 2 (770x400) RGBA4444 buffers (tiled buffer + linear). */
|
||||||
/* We use a single 1280x720 tiled RGB565 buffer. */
|
/* We use a single 1280x720 tiled RGB565 buffer. */
|
||||||
constexpr s32 raw_width = FatalScreenWidth;
|
constexpr s32 RawWidth = FatalScreenWidth;
|
||||||
constexpr s32 raw_height = FatalScreenHeight;
|
constexpr s32 RawHeight = FatalScreenHeight;
|
||||||
constexpr s32 layer_width = ((raw_width) * 3) / 2;
|
constexpr s32 LayerWidth = ((RawWidth) * 3) / 2;
|
||||||
constexpr s32 layer_height = ((raw_height) * 3) / 2;
|
constexpr s32 LayerHeight = ((RawHeight) * 3) / 2;
|
||||||
|
|
||||||
const float layer_x = static_cast<float>((display_width - layer_width) / 2);
|
const float layer_x = static_cast<float>((display_width - LayerWidth) / 2);
|
||||||
const float layer_y = static_cast<float>((display_height - layer_height) / 2);
|
const float layer_y = static_cast<float>((display_height - LayerHeight) / 2);
|
||||||
|
|
||||||
R_TRY(viSetLayerSize(&this->layer, layer_width, layer_height));
|
R_TRY(viSetLayerSize(&this->layer, LayerWidth, LayerHeight));
|
||||||
|
|
||||||
/* Set the layer's Z at display maximum, to be above everything else .*/
|
/* Set the layer's Z at display maximum, to be above everything else .*/
|
||||||
R_TRY(viSetLayerZ(&this->layer, FatalLayerZ));
|
R_TRY(viSetLayerZ(&this->layer, FatalLayerZ));
|
||||||
|
@ -210,7 +193,7 @@ namespace ams::fatal::srv {
|
||||||
|
|
||||||
/* Create framebuffer. */
|
/* Create framebuffer. */
|
||||||
R_TRY(nwindowCreateFromLayer(&this->win, &this->layer));
|
R_TRY(nwindowCreateFromLayer(&this->win, &this->layer));
|
||||||
R_TRY(framebufferCreate(&this->fb, &this->win, raw_width, raw_height, PIXEL_FORMAT_RGB_565, 1));
|
R_TRY(this->InitializeNativeWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
|
@ -450,6 +433,52 @@ namespace ams::fatal::srv {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ShowFatalTask::InitializeNativeWindow() {
|
||||||
|
/* Setup nv driver. */
|
||||||
|
R_TRY(nvInitialize());
|
||||||
|
R_TRY(nvMapInit());
|
||||||
|
R_TRY(nvFenceInit());
|
||||||
|
|
||||||
|
/* Create nvmap. */
|
||||||
|
R_TRY(nvMapCreate(&this->map, g_framebuffer_memory, sizeof(g_framebuffer_memory), 0x20000, NvKind_Pitch, true));
|
||||||
|
|
||||||
|
/* Setup graphics buffer. */
|
||||||
|
{
|
||||||
|
NvGraphicBuffer grbuf = {};
|
||||||
|
grbuf.header.num_ints = (sizeof(NvGraphicBuffer) - sizeof(NativeHandle)) / 4;
|
||||||
|
grbuf.unk0 = -1;
|
||||||
|
grbuf.magic = 0xDAFFCAFF;
|
||||||
|
grbuf.pid = 42;
|
||||||
|
grbuf.usage = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
|
||||||
|
grbuf.format = PIXEL_FORMAT_RGB_565;
|
||||||
|
grbuf.ext_format = PIXEL_FORMAT_RGB_565;
|
||||||
|
grbuf.num_planes = 1;
|
||||||
|
grbuf.planes[0].width = FatalScreenWidth;
|
||||||
|
grbuf.planes[0].height = FatalScreenHeight;
|
||||||
|
grbuf.planes[0].color_format = NvColorFormat_R5G6B5;
|
||||||
|
grbuf.planes[0].layout = NvLayout_BlockLinear;
|
||||||
|
grbuf.planes[0].kind = NvKind_Generic_16BX2;
|
||||||
|
grbuf.planes[0].block_height_log2 = 4;
|
||||||
|
grbuf.nvmap_id = nvMapGetId(&this->map);
|
||||||
|
grbuf.stride = FatalScreenWidthAligned;
|
||||||
|
grbuf.total_size = sizeof(g_framebuffer_memory);
|
||||||
|
grbuf.planes[0].pitch = FatalScreenWidthAlignedBytes;
|
||||||
|
grbuf.planes[0].size = sizeof(g_framebuffer_memory);
|
||||||
|
grbuf.planes[0].offset = 0;
|
||||||
|
|
||||||
|
R_TRY(nwindowConfigureBuffer(&this->win, 0, &grbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowFatalTask::DisplayPreRenderedFrame() {
|
||||||
|
s32 slot;
|
||||||
|
R_ABORT_UNLESS(nwindowDequeueBuffer(&this->win, &slot, nullptr));
|
||||||
|
dd::FlushDataCache(g_framebuffer_memory, sizeof(g_framebuffer_memory));
|
||||||
|
R_ABORT_UNLESS(nwindowQueueBuffer(&this->win, this->win.cur_slot, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
Result ShowFatalTask::ShowFatal() {
|
Result ShowFatalTask::ShowFatal() {
|
||||||
/* Pre-render the framebuffer. */
|
/* Pre-render the framebuffer. */
|
||||||
PreRenderFrameBuffer();
|
PreRenderFrameBuffer();
|
||||||
|
@ -459,14 +488,8 @@ namespace ams::fatal::srv {
|
||||||
R_ABORT_UNLESS(PrepareScreenForDrawing());
|
R_ABORT_UNLESS(PrepareScreenForDrawing());
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Dequeue a buffer. */
|
/* Display the pre-rendered frame. */
|
||||||
R_UNLESS(framebufferBegin(&this->fb, NULL) != nullptr, ResultNullGraphicsBuffer());
|
this->DisplayPreRenderedFrame();
|
||||||
|
|
||||||
/* We've already pre-rendered the frame into the static buffer. */
|
|
||||||
/* ... */
|
|
||||||
|
|
||||||
/* Enqueue the buffer. */
|
|
||||||
framebufferEnd(&fb);
|
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue