Print the found file entries after sorting
[openal-soft.git] / alc / alcontext.h
blobba3942f50bcbfc644164300d9b721ce260d3c12f
1 #ifndef ALCONTEXT_H
2 #define ALCONTEXT_H
4 #include <atomic>
5 #include <cstddef>
6 #include <cstdint>
7 #include <memory>
8 #include <mutex>
9 #include <thread>
10 #include <utility>
12 #include "AL/al.h"
13 #include "AL/alc.h"
15 #include "al/listener.h"
16 #include "almalloc.h"
17 #include "alnumeric.h"
18 #include "alu.h"
19 #include "atomic.h"
20 #include "inprogext.h"
21 #include "intrusive_ptr.h"
22 #include "logging.h"
23 #include "threads.h"
24 #include "vector.h"
25 #include "voice.h"
27 struct ALeffectslot;
28 struct ALeffectslotProps;
29 struct ALsource;
30 struct RingBuffer;
33 enum class DistanceModel {
34 InverseClamped = AL_INVERSE_DISTANCE_CLAMPED,
35 LinearClamped = AL_LINEAR_DISTANCE_CLAMPED,
36 ExponentClamped = AL_EXPONENT_DISTANCE_CLAMPED,
37 Inverse = AL_INVERSE_DISTANCE,
38 Linear = AL_LINEAR_DISTANCE,
39 Exponent = AL_EXPONENT_DISTANCE,
40 Disable = AL_NONE,
42 Default = InverseClamped
46 struct ALcontextProps {
47 ALfloat DopplerFactor;
48 ALfloat DopplerVelocity;
49 ALfloat SpeedOfSound;
50 ALboolean SourceDistanceModel;
51 DistanceModel mDistanceModel;
53 std::atomic<ALcontextProps*> next;
55 DEF_NEWDEL(ALcontextProps)
59 struct SourceSubList {
60 uint64_t FreeMask{~0_u64};
61 ALsource *Sources{nullptr}; /* 64 */
63 SourceSubList() noexcept = default;
64 SourceSubList(const SourceSubList&) = delete;
65 SourceSubList(SourceSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Sources{rhs.Sources}
66 { rhs.FreeMask = ~0_u64; rhs.Sources = nullptr; }
67 ~SourceSubList();
69 SourceSubList& operator=(const SourceSubList&) = delete;
70 SourceSubList& operator=(SourceSubList&& rhs) noexcept
71 { std::swap(FreeMask, rhs.FreeMask); std::swap(Sources, rhs.Sources); return *this; }
74 struct EffectSlotSubList {
75 uint64_t FreeMask{~0_u64};
76 ALeffectslot *EffectSlots{nullptr}; /* 64 */
78 EffectSlotSubList() noexcept = default;
79 EffectSlotSubList(const EffectSlotSubList&) = delete;
80 EffectSlotSubList(EffectSlotSubList&& rhs) noexcept
81 : FreeMask{rhs.FreeMask}, EffectSlots{rhs.EffectSlots}
82 { rhs.FreeMask = ~0_u64; rhs.EffectSlots = nullptr; }
83 ~EffectSlotSubList();
85 EffectSlotSubList& operator=(const EffectSlotSubList&) = delete;
86 EffectSlotSubList& operator=(EffectSlotSubList&& rhs) noexcept
87 { std::swap(FreeMask, rhs.FreeMask); std::swap(EffectSlots, rhs.EffectSlots); return *this; }
90 struct ALCcontext : public al::intrusive_ref<ALCcontext> {
91 al::vector<SourceSubList> mSourceList;
92 ALuint mNumSources{0};
93 std::mutex mSourceLock;
95 al::vector<EffectSlotSubList> mEffectSlotList;
96 ALuint mNumEffectSlots{0u};
97 std::mutex mEffectSlotLock;
99 std::atomic<ALenum> mLastError{AL_NO_ERROR};
101 DistanceModel mDistanceModel{DistanceModel::Default};
102 ALboolean mSourceDistanceModel{AL_FALSE};
104 ALfloat mDopplerFactor{1.0f};
105 ALfloat mDopplerVelocity{1.0f};
106 ALfloat mSpeedOfSound{SPEEDOFSOUNDMETRESPERSEC};
108 std::atomic_flag mPropsClean;
109 std::atomic<bool> mDeferUpdates{false};
111 std::mutex mPropLock;
113 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
114 * indicates if updates are currently happening).
116 RefCount mUpdateCount{0u};
117 std::atomic<bool> mHoldUpdates{false};
119 ALfloat mGainBoost{1.0f};
121 std::atomic<ALcontextProps*> mUpdate{nullptr};
123 /* Linked lists of unused property containers, free to use for future
124 * updates.
126 std::atomic<ALcontextProps*> mFreeContextProps{nullptr};
127 std::atomic<ALlistenerProps*> mFreeListenerProps{nullptr};
128 std::atomic<ALvoiceProps*> mFreeVoiceProps{nullptr};
129 std::atomic<ALeffectslotProps*> mFreeEffectslotProps{nullptr};
131 al::vector<ALvoice> mVoices;
133 using ALeffectslotArray = al::FlexArray<ALeffectslot*>;
134 std::atomic<ALeffectslotArray*> mActiveAuxSlots{nullptr};
136 std::thread mEventThread;
137 al::semaphore mEventSem;
138 std::unique_ptr<RingBuffer> mAsyncEvents;
139 std::atomic<ALbitfieldSOFT> mEnabledEvts{0u};
140 std::mutex mEventCbLock;
141 ALEVENTPROCSOFT mEventCb{};
142 void *mEventParam{nullptr};
144 /* Default effect slot */
145 std::unique_ptr<ALeffectslot> mDefaultSlot;
147 const al::intrusive_ptr<ALCdevice> mDevice;
148 const ALCchar *mExtensionList{nullptr};
150 ALlistener mListener{};
153 ALCcontext(al::intrusive_ptr<ALCdevice> device);
154 ALCcontext(const ALCcontext&) = delete;
155 ALCcontext& operator=(const ALCcontext&) = delete;
156 ~ALCcontext();
158 void init();
160 * Removes the context from its device and removes it from being current on
161 * the running thread or globally. Returns true if other contexts still
162 * exist on the device.
164 bool deinit();
167 * Defers/suspends updates for the given context's listener and sources.
168 * This does *NOT* stop mixing, but rather prevents certain property
169 * changes from taking effect.
171 void deferUpdates() noexcept { mDeferUpdates.store(true); }
173 /** Resumes update processing after being deferred. */
174 void processUpdates();
176 void setError(ALenum errorCode, const char *msg, ...) DECL_FORMAT(printf, 3, 4);
178 DEF_NEWDEL(ALCcontext)
181 #define SETERR_RETURN(ctx, err, retval, ...) do { \
182 (ctx)->setError((err), __VA_ARGS__); \
183 return retval; \
184 } while(0)
187 using ContextRef = al::intrusive_ptr<ALCcontext>;
189 ContextRef GetContextRef(void);
191 void UpdateContextProps(ALCcontext *context);
194 extern bool TrapALError;
196 #endif /* ALCONTEXT_H */