summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2019-02-06 12:33:13 -0500
committerGravatar GitHub2019-02-06 12:33:13 -0500
commit40cd299f01d7c77b98ceaad2867aafacca42131d (patch)
tree7aceb397364134a44d44875ce79503c4b0993622
parentMerge pull request #2088 from jroweboy/h (diff)
parentservice/nvflinger,service/vi: Handle failure cases with exposed API (diff)
downloadyuzu-40cd299f01d7c77b98ceaad2867aafacca42131d.tar.gz
yuzu-40cd299f01d7c77b98ceaad2867aafacca42131d.tar.xz
yuzu-40cd299f01d7c77b98ceaad2867aafacca42131d.zip
Merge pull request #2087 from lioncash/const
service/nvflinger, service/vi: Improve error case handling
-rw-r--r--src/core/hle/service/am/am.cpp7
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp92
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h25
-rw-r--r--src/core/hle/service/vi/vi.cpp62
4 files changed, 136 insertions, 50 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index d1cbe0e44..3f009d2b7 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -322,14 +322,15 @@ void ISelfController::SetScreenShotImageOrientation(Kernel::HLERequestContext& c
322 322
323void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) { 323void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) {
324 LOG_WARNING(Service_AM, "(STUBBED) called"); 324 LOG_WARNING(Service_AM, "(STUBBED) called");
325
325 // TODO(Subv): Find out how AM determines the display to use, for now just 326 // TODO(Subv): Find out how AM determines the display to use, for now just
326 // create the layer in the Default display. 327 // create the layer in the Default display.
327 u64 display_id = nvflinger->OpenDisplay("Default"); 328 const auto display_id = nvflinger->OpenDisplay("Default");
328 u64 layer_id = nvflinger->CreateLayer(display_id); 329 const auto layer_id = nvflinger->CreateLayer(*display_id);
329 330
330 IPC::ResponseBuilder rb{ctx, 4}; 331 IPC::ResponseBuilder rb{ctx, 4};
331 rb.Push(RESULT_SUCCESS); 332 rb.Push(RESULT_SUCCESS);
332 rb.Push(layer_id); 333 rb.Push(*layer_id);
333} 334}
334 335
335void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) { 336void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 8dfc0df03..cde06916d 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -46,7 +46,7 @@ void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) {
46 nvdrv = std::move(instance); 46 nvdrv = std::move(instance);
47} 47}
48 48
49u64 NVFlinger::OpenDisplay(std::string_view name) { 49std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) {
50 LOG_DEBUG(Service, "Opening \"{}\" display", name); 50 LOG_DEBUG(Service, "Opening \"{}\" display", name);
51 51
52 // TODO(Subv): Currently we only support the Default display. 52 // TODO(Subv): Currently we only support the Default display.
@@ -54,32 +54,48 @@ u64 NVFlinger::OpenDisplay(std::string_view name) {
54 54
55 const auto itr = std::find_if(displays.begin(), displays.end(), 55 const auto itr = std::find_if(displays.begin(), displays.end(),
56 [&](const Display& display) { return display.name == name; }); 56 [&](const Display& display) { return display.name == name; });
57 57 if (itr == displays.end()) {
58 ASSERT(itr != displays.end()); 58 return {};
59 }
59 60
60 return itr->id; 61 return itr->id;
61} 62}
62 63
63u64 NVFlinger::CreateLayer(u64 display_id) { 64std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
64 auto& display = FindDisplay(display_id); 65 auto* const display = FindDisplay(display_id);
66
67 if (display == nullptr) {
68 return {};
69 }
65 70
66 ASSERT_MSG(display.layers.empty(), "Only one layer is supported per display at the moment"); 71 ASSERT_MSG(display->layers.empty(), "Only one layer is supported per display at the moment");
67 72
68 const u64 layer_id = next_layer_id++; 73 const u64 layer_id = next_layer_id++;
69 const u32 buffer_queue_id = next_buffer_queue_id++; 74 const u32 buffer_queue_id = next_buffer_queue_id++;
70 auto buffer_queue = std::make_shared<BufferQueue>(buffer_queue_id, layer_id); 75 auto buffer_queue = std::make_shared<BufferQueue>(buffer_queue_id, layer_id);
71 display.layers.emplace_back(layer_id, buffer_queue); 76 display->layers.emplace_back(layer_id, buffer_queue);
72 buffer_queues.emplace_back(std::move(buffer_queue)); 77 buffer_queues.emplace_back(std::move(buffer_queue));
73 return layer_id; 78 return layer_id;
74} 79}
75 80
76u32 NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const { 81std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const {
77 const auto& layer = FindLayer(display_id, layer_id); 82 const auto* const layer = FindLayer(display_id, layer_id);
78 return layer.buffer_queue->GetId(); 83
84 if (layer == nullptr) {
85 return {};
86 }
87
88 return layer->buffer_queue->GetId();
79} 89}
80 90
81Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::GetVsyncEvent(u64 display_id) { 91Kernel::SharedPtr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
82 return FindDisplay(display_id).vsync_event.readable; 92 auto* const display = FindDisplay(display_id);
93
94 if (display == nullptr) {
95 return nullptr;
96 }
97
98 return display->vsync_event.readable;
83} 99}
84 100
85std::shared_ptr<BufferQueue> NVFlinger::FindBufferQueue(u32 id) const { 101std::shared_ptr<BufferQueue> NVFlinger::FindBufferQueue(u32 id) const {
@@ -90,40 +106,60 @@ std::shared_ptr<BufferQueue> NVFlinger::FindBufferQueue(u32 id) const {
90 return *itr; 106 return *itr;
91} 107}
92 108
93Display& NVFlinger::FindDisplay(u64 display_id) { 109Display* NVFlinger::FindDisplay(u64 display_id) {
94 const auto itr = std::find_if(displays.begin(), displays.end(), 110 const auto itr = std::find_if(displays.begin(), displays.end(),
95 [&](const Display& display) { return display.id == display_id; }); 111 [&](const Display& display) { return display.id == display_id; });
96 112
97 ASSERT(itr != displays.end()); 113 if (itr == displays.end()) {
98 return *itr; 114 return nullptr;
115 }
116
117 return &*itr;
99} 118}
100 119
101const Display& NVFlinger::FindDisplay(u64 display_id) const { 120const Display* NVFlinger::FindDisplay(u64 display_id) const {
102 const auto itr = std::find_if(displays.begin(), displays.end(), 121 const auto itr = std::find_if(displays.begin(), displays.end(),
103 [&](const Display& display) { return display.id == display_id; }); 122 [&](const Display& display) { return display.id == display_id; });
104 123
105 ASSERT(itr != displays.end()); 124 if (itr == displays.end()) {
106 return *itr; 125 return nullptr;
126 }
127
128 return &*itr;
107} 129}
108 130
109Layer& NVFlinger::FindLayer(u64 display_id, u64 layer_id) { 131Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) {
110 auto& display = FindDisplay(display_id); 132 auto* const display = FindDisplay(display_id);
111 133
112 const auto itr = std::find_if(display.layers.begin(), display.layers.end(), 134 if (display == nullptr) {
135 return nullptr;
136 }
137
138 const auto itr = std::find_if(display->layers.begin(), display->layers.end(),
113 [&](const Layer& layer) { return layer.id == layer_id; }); 139 [&](const Layer& layer) { return layer.id == layer_id; });
114 140
115 ASSERT(itr != display.layers.end()); 141 if (itr == display->layers.end()) {
116 return *itr; 142 return nullptr;
143 }
144
145 return &*itr;
117} 146}
118 147
119const Layer& NVFlinger::FindLayer(u64 display_id, u64 layer_id) const { 148const Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) const {
120 const auto& display = FindDisplay(display_id); 149 const auto* const display = FindDisplay(display_id);
150
151 if (display == nullptr) {
152 return nullptr;
153 }
121 154
122 const auto itr = std::find_if(display.layers.begin(), display.layers.end(), 155 const auto itr = std::find_if(display->layers.begin(), display->layers.end(),
123 [&](const Layer& layer) { return layer.id == layer_id; }); 156 [&](const Layer& layer) { return layer.id == layer_id; });
124 157
125 ASSERT(itr != display.layers.end()); 158 if (itr == display->layers.end()) {
126 return *itr; 159 return nullptr;
160 }
161
162 return &*itr;
127} 163}
128 164
129void NVFlinger::Compose() { 165void NVFlinger::Compose() {
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 83e974ed3..4c55e99f4 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -6,6 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <memory> 8#include <memory>
9#include <optional>
9#include <string> 10#include <string>
10#include <string_view> 11#include <string_view>
11#include <vector> 12#include <vector>
@@ -58,16 +59,24 @@ public:
58 void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance); 59 void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance);
59 60
60 /// Opens the specified display and returns the ID. 61 /// Opens the specified display and returns the ID.
61 u64 OpenDisplay(std::string_view name); 62 ///
63 /// If an invalid display name is provided, then an empty optional is returned.
64 std::optional<u64> OpenDisplay(std::string_view name);
62 65
63 /// Creates a layer on the specified display and returns the layer ID. 66 /// Creates a layer on the specified display and returns the layer ID.
64 u64 CreateLayer(u64 display_id); 67 ///
68 /// If an invalid display ID is specified, then an empty optional is returned.
69 std::optional<u64> CreateLayer(u64 display_id);
65 70
66 /// Finds the buffer queue ID of the specified layer in the specified display. 71 /// Finds the buffer queue ID of the specified layer in the specified display.
67 u32 FindBufferQueueId(u64 display_id, u64 layer_id) const; 72 ///
73 /// If an invalid display ID or layer ID is provided, then an empty optional is returned.
74 std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id) const;
68 75
69 /// Gets the vsync event for the specified display. 76 /// Gets the vsync event for the specified display.
70 Kernel::SharedPtr<Kernel::ReadableEvent> GetVsyncEvent(u64 display_id); 77 ///
78 /// If an invalid display ID is provided, then nullptr is returned.
79 Kernel::SharedPtr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const;
71 80
72 /// Obtains a buffer queue identified by the ID. 81 /// Obtains a buffer queue identified by the ID.
73 std::shared_ptr<BufferQueue> FindBufferQueue(u32 id) const; 82 std::shared_ptr<BufferQueue> FindBufferQueue(u32 id) const;
@@ -78,16 +87,16 @@ public:
78 87
79private: 88private:
80 /// Finds the display identified by the specified ID. 89 /// Finds the display identified by the specified ID.
81 Display& FindDisplay(u64 display_id); 90 Display* FindDisplay(u64 display_id);
82 91
83 /// Finds the display identified by the specified ID. 92 /// Finds the display identified by the specified ID.
84 const Display& FindDisplay(u64 display_id) const; 93 const Display* FindDisplay(u64 display_id) const;
85 94
86 /// Finds the layer identified by the specified ID in the desired display. 95 /// Finds the layer identified by the specified ID in the desired display.
87 Layer& FindLayer(u64 display_id, u64 layer_id); 96 Layer* FindLayer(u64 display_id, u64 layer_id);
88 97
89 /// Finds the layer identified by the specified ID in the desired display. 98 /// Finds the layer identified by the specified ID in the desired display.
90 const Layer& FindLayer(u64 display_id, u64 layer_id) const; 99 const Layer* FindLayer(u64 display_id, u64 layer_id) const;
91 100
92 std::shared_ptr<Nvidia::Module> nvdrv; 101 std::shared_ptr<Nvidia::Module> nvdrv;
93 102
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index fe08c38f2..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 {
34 34
35constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1}; 35constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1};
36constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6}; 36constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6};
37constexpr ResultCode ERR_NOT_FOUND{ErrorModule::VI, 7};
37 38
38struct DisplayInfo { 39struct DisplayInfo {
39 /// The name of this particular display. 40 /// The name of this particular display.
@@ -838,11 +839,16 @@ private:
838 "(STUBBED) called. unknown=0x{:08X}, display=0x{:016X}, aruid=0x{:016X}", 839 "(STUBBED) called. unknown=0x{:08X}, display=0x{:016X}, aruid=0x{:016X}",
839 unknown, display, aruid); 840 unknown, display, aruid);
840 841
841 const u64 layer_id = nv_flinger->CreateLayer(display); 842 const auto layer_id = nv_flinger->CreateLayer(display);
843 if (!layer_id) {
844 IPC::ResponseBuilder rb{ctx, 2};
845 rb.Push(ERR_NOT_FOUND);
846 return;
847 }
842 848
843 IPC::ResponseBuilder rb{ctx, 4}; 849 IPC::ResponseBuilder rb{ctx, 4};
844 rb.Push(RESULT_SUCCESS); 850 rb.Push(RESULT_SUCCESS);
845 rb.Push(layer_id); 851 rb.Push(*layer_id);
846 } 852 }
847 853
848 void AddToLayerStack(Kernel::HLERequestContext& ctx) { 854 void AddToLayerStack(Kernel::HLERequestContext& ctx) {
@@ -950,9 +956,16 @@ private:
950 956
951 ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet"); 957 ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet");
952 958
959 const auto display_id = nv_flinger->OpenDisplay(name);
960 if (!display_id) {
961 IPC::ResponseBuilder rb{ctx, 2};
962 rb.Push(ERR_NOT_FOUND);
963 return;
964 }
965
953 IPC::ResponseBuilder rb{ctx, 4}; 966 IPC::ResponseBuilder rb{ctx, 4};
954 rb.Push(RESULT_SUCCESS); 967 rb.Push(RESULT_SUCCESS);
955 rb.Push<u64>(nv_flinger->OpenDisplay(name)); 968 rb.Push<u64>(*display_id);
956 } 969 }
957 970
958 void CloseDisplay(Kernel::HLERequestContext& ctx) { 971 void CloseDisplay(Kernel::HLERequestContext& ctx) {
@@ -1043,10 +1056,21 @@ private:
1043 1056
1044 LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid); 1057 LOG_DEBUG(Service_VI, "called. layer_id=0x{:016X}, aruid=0x{:016X}", layer_id, aruid);
1045 1058
1046 const u64 display_id = nv_flinger->OpenDisplay(display_name); 1059 const auto display_id = nv_flinger->OpenDisplay(display_name);
1047 const u32 buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, layer_id); 1060 if (!display_id) {
1061 IPC::ResponseBuilder rb{ctx, 2};
1062 rb.Push(ERR_NOT_FOUND);
1063 return;
1064 }
1065
1066 const auto buffer_queue_id = nv_flinger->FindBufferQueueId(*display_id, layer_id);
1067 if (!buffer_queue_id) {
1068 IPC::ResponseBuilder rb{ctx, 2};
1069 rb.Push(ERR_NOT_FOUND);
1070 return;
1071 }
1048 1072
1049 NativeWindow native_window{buffer_queue_id}; 1073 NativeWindow native_window{*buffer_queue_id};
1050 IPC::ResponseBuilder rb{ctx, 4}; 1074 IPC::ResponseBuilder rb{ctx, 4};
1051 rb.Push(RESULT_SUCCESS); 1075 rb.Push(RESULT_SUCCESS);
1052 rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); 1076 rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize()));
@@ -1062,13 +1086,24 @@ private:
1062 1086
1063 // TODO(Subv): What's the difference between a Stray and a Managed layer? 1087 // TODO(Subv): What's the difference between a Stray and a Managed layer?
1064 1088
1065 const u64 layer_id = nv_flinger->CreateLayer(display_id); 1089 const auto layer_id = nv_flinger->CreateLayer(display_id);
1066 const u32 buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, layer_id); 1090 if (!layer_id) {
1091 IPC::ResponseBuilder rb{ctx, 2};
1092 rb.Push(ERR_NOT_FOUND);
1093 return;
1094 }
1095
1096 const auto buffer_queue_id = nv_flinger->FindBufferQueueId(display_id, *layer_id);
1097 if (!buffer_queue_id) {
1098 IPC::ResponseBuilder rb{ctx, 2};
1099 rb.Push(ERR_NOT_FOUND);
1100 return;
1101 }
1067 1102
1068 NativeWindow native_window{buffer_queue_id}; 1103 NativeWindow native_window{*buffer_queue_id};
1069 IPC::ResponseBuilder rb{ctx, 6}; 1104 IPC::ResponseBuilder rb{ctx, 6};
1070 rb.Push(RESULT_SUCCESS); 1105 rb.Push(RESULT_SUCCESS);
1071 rb.Push(layer_id); 1106 rb.Push(*layer_id);
1072 rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); 1107 rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize()));
1073 } 1108 }
1074 1109
@@ -1088,7 +1123,12 @@ private:
1088 1123
1089 LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id); 1124 LOG_WARNING(Service_VI, "(STUBBED) called. display_id=0x{:016X}", display_id);
1090 1125
1091 const auto vsync_event = nv_flinger->GetVsyncEvent(display_id); 1126 const auto vsync_event = nv_flinger->FindVsyncEvent(display_id);
1127 if (!vsync_event) {
1128 IPC::ResponseBuilder rb{ctx, 2};
1129 rb.Push(ERR_NOT_FOUND);
1130 return;
1131 }
1092 1132
1093 IPC::ResponseBuilder rb{ctx, 2, 1}; 1133 IPC::ResponseBuilder rb{ctx, 2, 1};
1094 rb.Push(RESULT_SUCCESS); 1134 rb.Push(RESULT_SUCCESS);