[core, display, overlay] Add LayerIsOverlay to separate overlay on composer, stub RequestListSummaryOverlayNotification, sync emu settings when setting language (#3123)

This should fix the issue with, for example, ToTK running at 60 FPS when overlay applet is running.
This also should always run the overlay as actual overlay and not in the back.
Stubs RequestListSummaryOverlayNotifications in friends
Syncs Language of the Emulator, when setting language, this is used in Starter Applet

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3123
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com>
Co-authored-by: Maufeat <sahyno1996@gmail.com>
Co-committed-by: Maufeat <sahyno1996@gmail.com>
This commit is contained in:
Maufeat 2025-12-17 06:26:02 +01:00 committed by crueter
parent 50f8d4130d
commit 1eed7efd09
No known key found for this signature in database
GPG key ID: 425ACD2D4830EBC6
18 changed files with 223 additions and 76 deletions

View file

@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

View file

@ -166,6 +166,16 @@ Result Container::GetLayerZIndex(u64 layer_id, s32* out_z_index) {
R_RETURN(VI::ResultNotFound);
}
Result Container::SetLayerIsOverlay(u64 layer_id, bool is_overlay) {
std::scoped_lock lk{m_lock};
auto* const layer = m_layers.GetLayerById(layer_id);
R_UNLESS(layer != nullptr, VI::ResultNotFound);
m_surface_flinger->SetLayerIsOverlay(layer->GetConsumerBinderId(), is_overlay);
R_SUCCEED();
}
void Container::LinkVsyncEvent(u64 display_id, Event* event) {
std::scoped_lock lk{m_lock};
m_conductor->LinkVsyncEvent(display_id, event);

View file

@ -67,6 +67,7 @@ public:
Result SetLayerBlending(u64 layer_id, bool enabled);
Result SetLayerZIndex(u64 layer_id, s32 z_index);
Result GetLayerZIndex(u64 layer_id, s32* out_z_index);
Result SetLayerIsOverlay(u64 layer_id, bool is_overlay);
void LinkVsyncEvent(u64 display_id, Event* event);
void UnlinkVsyncEvent(u64 display_id, Event* event);

View file

@ -46,8 +46,8 @@ Result AllocateSharedBufferMemory(std::unique_ptr<Kernel::KPageGroup>* out_page_
u32* start = system.DeviceMemory().GetPointer<u32>(block.GetAddress());
u32* end = system.DeviceMemory().GetPointer<u32>(block.GetAddress() + block.GetSize());
for (; start < end; ++start) {
*start = 0x00000000; // ARGB/RGBA with alpha=0
for (; start < end; start++) {
*start = 0xFF0000FF;
}
}
@ -257,7 +257,6 @@ Result SharedBufferManager::CreateSession(Kernel::KProcess* owner_process, u64*
// Configure blending and z-index
R_ASSERT(m_container.SetLayerBlending(session.layer_id, enable_blending));
R_ASSERT(m_container.SetLayerZIndex(session.layer_id, 100000));
// Get the producer and set preallocated buffers.
std::shared_ptr<android::BufferQueueProducer> producer;
@ -374,11 +373,6 @@ Result SharedBufferManager::PresentSharedFrameBuffer(android::Fence fence,
android::Status::NoError,
VI::ResultOperationFailed);
// Ensure the layer is visible when content is presented.
// Re-assert overlay priority in case clients reset it.
(void)m_container.SetLayerZIndex(layer_id, 100000);
(void)m_container.SetLayerVisibility(layer_id, true);
// We succeeded.
R_SUCCEED();
}
@ -415,51 +409,22 @@ Result SharedBufferManager::WriteAppletCaptureBuffer(bool* out_was_written, s32*
// TODO: this could be optimized
s64 e = -1280 * 768 * 4;
for (auto& block : *m_buffer_page_group) {
u8* const block_start = m_system.DeviceMemory().GetPointer<u8>(block.GetAddress());
u8* ptr = block_start;
u8* const block_end = m_system.DeviceMemory().GetPointer<u8>(block.GetAddress() + block.GetSize());
u8* start = m_system.DeviceMemory().GetPointer<u8>(block.GetAddress());
u8* end = m_system.DeviceMemory().GetPointer<u8>(block.GetAddress() + block.GetSize());
for (; ptr < block_end; ++ptr) {
for (; start < end; start++) {
*start = 0;
if (e >= 0 && e < static_cast<s64>(capture_buffer.size())) {
*ptr = capture_buffer[static_cast<size_t>(e)];
} else {
*ptr = 0;
*start = capture_buffer[e];
}
++e;
e++;
}
m_system.GPU().Host1x().MemoryManager().ApplyOpOnPointer(block_start, scratch, [&](DAddr addr) {
m_system.GPU().InvalidateRegion(addr, block_end - block_start);
m_system.GPU().Host1x().MemoryManager().ApplyOpOnPointer(start, scratch, [&](DAddr addr) {
m_system.GPU().InvalidateRegion(addr, end - start);
});
}
// After writing, present a frame on each active shared layer so it becomes visible.
for (auto& [aruid, session] : m_sessions) {
std::shared_ptr<android::BufferQueueProducer> producer;
if (R_FAILED(m_container.GetLayerProducerHandle(std::addressof(producer), session.layer_id))) {
continue;
}
s32 slot = -1;
android::Fence fence = android::Fence::NoFence();
if (producer->DequeueBuffer(&slot, &fence, SharedBufferAsync != 0, SharedBufferWidth,
SharedBufferHeight, SharedBufferBlockLinearFormat, 0) !=
android::Status::NoError) {
continue;
}
std::shared_ptr<android::GraphicBuffer> gb;
if (producer->RequestBuffer(slot, &gb) != android::Status::NoError) {
producer->CancelBuffer(slot, android::Fence::NoFence());
continue;
}
android::QueueBufferInput qin{};
android::QueueBufferOutput qout{};
qin.crop = {0, 0, static_cast<s32>(SharedBufferWidth), static_cast<s32>(SharedBufferHeight)};
qin.fence = android::Fence::NoFence();
qin.transform = static_cast<android::NativeWindowTransform>(0);
qin.swap_interval = 1;
(void)producer->QueueBuffer(slot, qin, &qout);
}
*out_was_written = true;
*out_layer_index = 1;
R_SUCCEED();