1 // Copyright 2021 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <cstdint>
18 #include <functional>
19 #include <optional>
20 #include <sstream>
21 
22 namespace emugl {
23 
24 typedef int32_t VkResult;
25 
26 enum GfxstreamAbortReason : int64_t {
27     VK_RESULT = 0,
28     ABORT_REASON_OTHER =
29         4'300'000'000  // VkResult is 32-bit, so we pick this to be outside the 32-bit range.
30 };
31 
32 struct FatalError {
33     const GfxstreamAbortReason abort_reason;
34     const VkResult vk_result;
35 
FatalErrorFatalError36     explicit FatalError(GfxstreamAbortReason ab_reason)
37         : abort_reason(ab_reason), vk_result(0) {}
38     explicit FatalError(VkResult vk_result) : abort_reason(VK_RESULT), vk_result(vk_result) {}
39 
40     inline int64_t getAbortCode() const {
41         return abort_reason == VK_RESULT ? static_cast<int64_t>(vk_result) : abort_reason;
42     }
43 };
44 
45 class AbortMessage {
46    public:
47     AbortMessage(const char* file, const char* function, int line, FatalError reason);
48 
49     [[noreturn]] ~AbortMessage();
50 
51     std::ostream& stream() { return mOss; }
52 
53    private:
54     const char* const mFile;
55     const char* const mFunction;
56     const int mLine;
57     const FatalError mReason;
58     std::ostringstream mOss;
59 };
60 
61 // A function that terminates the process should be passed in. When calling the GFXSTREAM_ABORT
62 // macro, the set function will be used to terminate the process instead of std::abort.
63 void setDieFunction(std::optional<std::function<void()>> newDie);
64 }  // namespace emugl
65 
66 #define GFXSTREAM_ABORT(reason) ::emugl::AbortMessage(__FILE__, __func__, __LINE__, reason).stream()
67 
68 #define FATAL() GFXSTREAM_ABORT(::emugl::FatalError(ABORT_REASON_OTHER))
69