diff options
| author | Lioncash <mathew1800@gmail.com> | 2019-02-05 16:20:04 -0500 |
|---|---|---|
| committer | Lioncash <mathew1800@gmail.com> | 2019-02-05 18:03:28 -0500 |
| commit | ef073ff117752274f374443756652fdda9c44773 (patch) | |
| tree | 3453e2c21a4aec602f5ee9a308cad23463d9dad3 /src/core/hle/service/vi/vi.cpp | |
| parent | 7320c667dfa8993f4ebec8d6adfbf954d0591784 (diff) | |
service/nvflinger,service/vi: Handle failure cases with exposed API
Converts many of the Find* functions to return a std::optional<T> as
opposed to returning the raw return values directly. This allows
removing a few assertions and handles error cases like the service
itself does.
Diffstat (limited to 'src/core/hle/service/vi/vi.cpp')
| -rw-r--r-- | src/core/hle/service/vi/vi.cpp | 60 |
1 files changed, 50 insertions, 10 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 724d48df8..a317a2885 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -34,6 +34,7 @@ namespace Service::VI { constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1}; constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6}; +constexpr ResultCode ERR_NOT_FOUND{ErrorModule::VI, 7}; struct DisplayInfo { /// The name of this particular display. @@ -838,11 +839,16 @@ private: "(STUBBED) called. unknown=0x{:08X}, display=0x{:016X}, aruid=0x{:016X}", unknown, display, aruid); - const u64 layer_id = nv_flinger->CreateLayer(display); + const auto layer_id = nv_flinger->CreateLayer(display); + if (!layer_id) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NOT_FOUND); + return; + } IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.Push(layer_id); + rb.Push(*layer_id); } void AddToLayerStack(Kernel::HLERequestContext& ctx) { @@ -950,9 +956,16 @@ private: ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet"); + const auto display_id = nv_flinger->OpenDisplay(name); + if (!display_id) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NOT_FOUND); + return; + } + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.Push<u64>(nv_flinger->OpenDisplay(name)); + rb.Push<u64>(*display_id); } void CloseDisplay(Kernel::HLERequestContext& ctx) { @@ -1043,10 +1056,21 @@ private: LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid); - const u64 display_id = nv_flinger->OpenDisplay(display_name); - const u32 buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, layer_id); + const auto display_id = nv_flinger->OpenDisplay(display_name); + if (!display_id) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NOT_FOUND); + return; + } + + const auto buffer_queue_id = nv_flinger->FindBufferQueueId(*display_id, layer_id); + if (!buffer_queue_id) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NOT_FOUND); + return; + } - NativeWindow native_window{buffer_queue_id}; + NativeWindow native_window{*buffer_queue_id}; IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); @@ -1062,13 +1086,24 @@ private: // TODO(Subv): What's the difference between a Stray and a Managed layer? - const u64 layer_id = nv_flinger->CreateLayer(display_id); - const u32 buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, layer_id); + const auto layer_id = nv_flinger->CreateLayer(display_id); + if (!layer_id) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NOT_FOUND); + return; + } + + const auto buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, *layer_id); + if (!buffer_queue_id) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NOT_FOUND); + return; + } - NativeWindow native_window{buffer_queue_id}; + NativeWindow native_window{*buffer_queue_id}; IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); - rb.Push(layer_id); + rb.Push(*layer_id); rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); } @@ -1089,6 +1124,11 @@ private: LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id); const auto vsync_event = nv_flinger->FindVsyncEvent(display_id); + if (!vsync_event) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NOT_FOUND); + return; + } IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); |
