summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/vi/vi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/vi/vi.cpp')
-rw-r--r--src/core/hle/service/vi/vi.cpp74
1 files changed, 45 insertions, 29 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 9ab8788e3..1f3d82c57 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -15,6 +15,7 @@
#include "common/logging/log.h"
#include "common/math_util.h"
#include "common/settings.h"
+#include "common/string_util.h"
#include "common/swap.h"
#include "core/core_timing.h"
#include "core/hle/kernel/k_readable_event.h"
@@ -343,8 +344,8 @@ private:
class IManagerDisplayService final : public ServiceFramework<IManagerDisplayService> {
public:
- explicit IManagerDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_)
- : ServiceFramework{system_, "IManagerDisplayService"}, nv_flinger{nv_flinger_} {
+ explicit IManagerDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger_)
+ : ServiceFramework{system_, "IManagerDisplayService"}, nvnflinger{nvnflinger_} {
// clang-format off
static const FunctionInfo functions[] = {
{200, nullptr, "AllocateProcessHeapBlock"},
@@ -440,7 +441,7 @@ private:
IPC::RequestParser rp{ctx};
const u64 display = rp.Pop<u64>();
- const Result rc = nv_flinger.CloseDisplay(display) ? ResultSuccess : ResultUnknown;
+ const Result rc = nvnflinger.CloseDisplay(display) ? ResultSuccess : ResultUnknown;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
@@ -457,7 +458,7 @@ private:
"(STUBBED) called. unknown=0x{:08X}, display=0x{:016X}, aruid=0x{:016X}",
unknown, display, aruid);
- const auto layer_id = nv_flinger.CreateLayer(display);
+ const auto layer_id = nvnflinger.CreateLayer(display);
if (!layer_id) {
LOG_ERROR(Service_VI, "Layer not found! display=0x{:016X}", display);
IPC::ResponseBuilder rb{ctx, 2};
@@ -494,14 +495,14 @@ private:
rb.Push(ResultSuccess);
}
- Nvnflinger::Nvnflinger& nv_flinger;
+ Nvnflinger::Nvnflinger& nvnflinger;
};
class IApplicationDisplayService final : public ServiceFramework<IApplicationDisplayService> {
public:
- IApplicationDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nv_flinger_,
+ IApplicationDisplayService(Core::System& system_, Nvnflinger::Nvnflinger& nvnflinger_,
Nvnflinger::HosBinderDriverServer& hos_binder_driver_server_)
- : ServiceFramework{system_, "IApplicationDisplayService"}, nv_flinger{nv_flinger_},
+ : ServiceFramework{system_, "IApplicationDisplayService"}, nvnflinger{nvnflinger_},
hos_binder_driver_server{hos_binder_driver_server_} {
static const FunctionInfo functions[] = {
@@ -564,7 +565,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<ISystemDisplayService>(system, nv_flinger);
+ rb.PushIpcInterface<ISystemDisplayService>(system, nvnflinger);
}
void GetManagerDisplayService(HLERequestContext& ctx) {
@@ -572,7 +573,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<IManagerDisplayService>(system, nv_flinger);
+ rb.PushIpcInterface<IManagerDisplayService>(system, nvnflinger);
}
void GetIndirectDisplayTransactionService(HLERequestContext& ctx) {
@@ -607,7 +608,7 @@ private:
ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet");
- const auto display_id = nv_flinger.OpenDisplay(name);
+ const auto display_id = nvnflinger.OpenDisplay(name);
if (!display_id) {
LOG_ERROR(Service_VI, "Display not found! display_name={}", name);
IPC::ResponseBuilder rb{ctx, 2};
@@ -624,7 +625,7 @@ private:
IPC::RequestParser rp{ctx};
const u64 display_id = rp.Pop<u64>();
- const Result rc = nv_flinger.CloseDisplay(display_id) ? ResultSuccess : ResultUnknown;
+ const Result rc = nvnflinger.CloseDisplay(display_id) ? ResultSuccess : ResultUnknown;
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(rc);
@@ -694,16 +695,14 @@ private:
void OpenLayer(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto name_buf = rp.PopRaw<std::array<u8, 0x40>>();
- const auto end = std::find(name_buf.begin(), name_buf.end(), '\0');
-
- const std::string display_name(name_buf.begin(), end);
+ const std::string display_name(Common::StringFromBuffer(name_buf));
const u64 layer_id = rp.Pop<u64>();
const u64 aruid = rp.Pop<u64>();
LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid);
- const auto display_id = nv_flinger.OpenDisplay(display_name);
+ const auto display_id = nvnflinger.OpenDisplay(display_name);
if (!display_id) {
LOG_ERROR(Service_VI, "Layer not found! layer_id={}", layer_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -711,7 +710,7 @@ private:
return;
}
- const auto buffer_queue_id = nv_flinger.FindBufferQueueId(*display_id, layer_id);
+ const auto buffer_queue_id = nvnflinger.FindBufferQueueId(*display_id, layer_id);
if (!buffer_queue_id) {
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", *display_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -719,7 +718,12 @@ private:
return;
}
- nv_flinger.OpenLayer(layer_id);
+ if (!nvnflinger.OpenLayer(layer_id)) {
+ LOG_WARNING(Service_VI, "Tried to open layer which was already open");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultOperationFailed);
+ return;
+ }
android::OutputParcel parcel;
parcel.WriteInterface(NativeWindow{*buffer_queue_id});
@@ -737,7 +741,12 @@ private:
LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}", layer_id);
- nv_flinger.CloseLayer(layer_id);
+ if (!nvnflinger.CloseLayer(layer_id)) {
+ LOG_WARNING(Service_VI, "Tried to close layer which was not open");
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultOperationFailed);
+ return;
+ }
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -753,7 +762,7 @@ private:
// TODO(Subv): What's the difference between a Stray and a Managed layer?
- const auto layer_id = nv_flinger.CreateLayer(display_id);
+ const auto layer_id = nvnflinger.CreateLayer(display_id);
if (!layer_id) {
LOG_ERROR(Service_VI, "Layer not found! display_id={}", display_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -761,7 +770,7 @@ private:
return;
}
- const auto buffer_queue_id = nv_flinger.FindBufferQueueId(display_id, *layer_id);
+ const auto buffer_queue_id = nvnflinger.FindBufferQueueId(display_id, *layer_id);
if (!buffer_queue_id) {
LOG_ERROR(Service_VI, "Buffer queue id not found! display_id={}", display_id);
IPC::ResponseBuilder rb{ctx, 2};
@@ -785,7 +794,7 @@ private:
const u64 layer_id = rp.Pop<u64>();
LOG_WARNING(Service_VI, "(STUBBED) called. layer_id=0x{:016X}", layer_id);
- nv_flinger.DestroyLayer(layer_id);
+ nvnflinger.DestroyLayer(layer_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@@ -798,7 +807,7 @@ private:
LOG_DEBUG(Service_VI, "called. display_id={}", display_id);
Kernel::KReadableEvent* vsync_event{};
- const auto result = nv_flinger.FindVsyncEvent(&vsync_event, display_id);
+ const auto result = nvnflinger.FindVsyncEvent(&vsync_event, display_id);
if (result != ResultSuccess) {
if (result == ResultNotFound) {
LOG_ERROR(Service_VI, "Vsync event was not found for display_id={}", display_id);
@@ -808,6 +817,12 @@ private:
rb.Push(result);
return;
}
+ if (vsync_event_fetched) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(VI::ResultPermissionDenied);
+ return;
+ }
+ vsync_event_fetched = true;
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess);
@@ -899,8 +914,9 @@ private:
}
}
- Nvnflinger::Nvnflinger& nv_flinger;
+ Nvnflinger::Nvnflinger& nvnflinger;
Nvnflinger::HosBinderDriverServer& hos_binder_driver_server;
+ bool vsync_event_fetched{false};
};
static bool IsValidServiceAccess(Permission permission, Policy policy) {
@@ -916,7 +932,7 @@ static bool IsValidServiceAccess(Permission permission, Policy policy) {
}
void detail::GetDisplayServiceImpl(HLERequestContext& ctx, Core::System& system,
- Nvnflinger::Nvnflinger& nv_flinger,
+ Nvnflinger::Nvnflinger& nvnflinger,
Nvnflinger::HosBinderDriverServer& hos_binder_driver_server,
Permission permission) {
IPC::RequestParser rp{ctx};
@@ -931,19 +947,19 @@ void detail::GetDisplayServiceImpl(HLERequestContext& ctx, Core::System& system,
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger, hos_binder_driver_server);
+ rb.PushIpcInterface<IApplicationDisplayService>(system, nvnflinger, hos_binder_driver_server);
}
-void LoopProcess(Core::System& system, Nvnflinger::Nvnflinger& nv_flinger,
+void LoopProcess(Core::System& system, Nvnflinger::Nvnflinger& nvnflinger,
Nvnflinger::HosBinderDriverServer& hos_binder_driver_server) {
auto server_manager = std::make_unique<ServerManager>(system);
server_manager->RegisterNamedService(
- "vi:m", std::make_shared<VI_M>(system, nv_flinger, hos_binder_driver_server));
+ "vi:m", std::make_shared<VI_M>(system, nvnflinger, hos_binder_driver_server));
server_manager->RegisterNamedService(
- "vi:s", std::make_shared<VI_S>(system, nv_flinger, hos_binder_driver_server));
+ "vi:s", std::make_shared<VI_S>(system, nvnflinger, hos_binder_driver_server));
server_manager->RegisterNamedService(
- "vi:u", std::make_shared<VI_U>(system, nv_flinger, hos_binder_driver_server));
+ "vi:u", std::make_shared<VI_U>(system, nvnflinger, hos_binder_driver_server));
ServerManager::RunServer(std::move(server_manager));
}