12 #include "inprogext.h"
19 #include "alListener.h"
24 struct ALcontextProps
;
25 struct ALlistenerProps
;
27 struct ALeffectslotProps
;
29 struct ALeffectslotArray
;
32 enum class DistanceModel
{
33 InverseClamped
= AL_INVERSE_DISTANCE_CLAMPED
,
34 LinearClamped
= AL_LINEAR_DISTANCE_CLAMPED
,
35 ExponentClamped
= AL_EXPONENT_DISTANCE_CLAMPED
,
36 Inverse
= AL_INVERSE_DISTANCE
,
37 Linear
= AL_LINEAR_DISTANCE
,
38 Exponent
= AL_EXPONENT_DISTANCE
,
41 Default
= InverseClamped
44 struct SourceSubList
{
45 uint64_t FreeMask
{0u};
46 ALsource
*Sources
{nullptr}; /* 64 */
49 /* Effect slots are rather large, and apps aren't likely to have more than one
50 * or two (let alone 64), so hold them individually.
52 using ALeffectslotPtr
= std::unique_ptr
<ALeffectslot
>;
54 struct ALCcontext_struct
{
57 al::vector
<SourceSubList
> SourceList
;
61 al::vector
<ALeffectslotPtr
> EffectSlotList
;
62 almtx_t EffectSlotLock
;
64 ATOMIC(ALenum
) LastError
{AL_NO_ERROR
};
66 DistanceModel mDistanceModel
{DistanceModel::Default
};
67 ALboolean SourceDistanceModel
{AL_FALSE
};
69 ALfloat DopplerFactor
{1.0f
};
70 ALfloat DopplerVelocity
{1.0f
};
71 ALfloat SpeedOfSound
{};
72 ALfloat MetersPerUnit
{1.0f
};
74 std::atomic_flag PropsClean
{true};
75 std::atomic
<bool> DeferUpdates
{false};
79 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
80 * indicates if updates are currently happening).
82 RefCount UpdateCount
{0u};
83 ATOMIC(ALenum
) HoldUpdates
{AL_FALSE
};
85 ALfloat GainBoost
{1.0f
};
87 ATOMIC(ALcontextProps
*) Update
{nullptr};
89 /* Linked lists of unused property containers, free to use for future
92 ATOMIC(ALcontextProps
*) FreeContextProps
{nullptr};
93 ATOMIC(ALlistenerProps
*) FreeListenerProps
{nullptr};
94 ATOMIC(ALvoiceProps
*) FreeVoiceProps
{nullptr};
95 ATOMIC(ALeffectslotProps
*) FreeEffectslotProps
{nullptr};
97 ALvoice
**Voices
{nullptr};
98 ALsizei VoiceCount
{0};
101 ATOMIC(ALeffectslotArray
*) ActiveAuxSlots
{nullptr};
103 std::thread EventThread
;
105 ll_ringbuffer
*AsyncEvents
{nullptr};
106 ATOMIC(ALbitfieldSOFT
) EnabledEvts
{0u};
107 std::mutex EventCbLock
;
108 ALEVENTPROCSOFT EventCb
{};
109 void *EventParam
{nullptr};
111 /* Default effect slot */
112 std::unique_ptr
<ALeffectslot
> DefaultSlot
;
114 ALCdevice
*const Device
;
115 const ALCchar
*ExtensionList
{nullptr};
117 ATOMIC(ALCcontext
*) next
{nullptr};
119 ALlistener Listener
{};
122 ALCcontext_struct(ALCdevice
*device
);
123 ALCcontext_struct(const ALCcontext_struct
&) = delete;
124 ALCcontext_struct
& operator=(const ALCcontext_struct
&) = delete;
125 ~ALCcontext_struct();
127 DEF_NEWDEL(ALCcontext
)
130 ALCcontext
*GetContextRef(void);
131 void ALCcontext_DecRef(ALCcontext
*context
);
133 void UpdateContextProps(ALCcontext
*context
);
135 void ALCcontext_DeferUpdates(ALCcontext
*context
);
136 void ALCcontext_ProcessUpdates(ALCcontext
*context
);
139 /* Simple RAII context reference. Takes the reference of the provided
140 * ALCcontext, and decrements it when leaving scope. Movable (transfer
141 * reference) but not copyable (no new references).
144 ALCcontext
*mCtx
{nullptr};
146 void reset() noexcept
149 ALCcontext_DecRef(mCtx
);
154 ContextRef() noexcept
= default;
155 ContextRef(ContextRef
&& rhs
) noexcept
: mCtx
{rhs
.mCtx
}
156 { rhs
.mCtx
= nullptr; }
157 explicit ContextRef(ALCcontext
*ctx
) noexcept
: mCtx(ctx
) { }
158 ~ContextRef() { reset(); }
160 ContextRef
& operator=(const ContextRef
&) = delete;
161 ContextRef
& operator=(ContextRef
&& rhs
) noexcept
169 operator bool() const noexcept
{ return mCtx
!= nullptr; }
171 ALCcontext
* operator->() noexcept
{ return mCtx
; }
172 ALCcontext
* get() noexcept
{ return mCtx
; }
174 ALCcontext
* release() noexcept
176 ALCcontext
*ret
{mCtx
};
183 struct ALcontextProps
{
184 ALfloat DopplerFactor
;
185 ALfloat DopplerVelocity
;
186 ALfloat SpeedOfSound
;
187 ALboolean SourceDistanceModel
;
188 DistanceModel mDistanceModel
;
189 ALfloat MetersPerUnit
;
191 ATOMIC(struct ALcontextProps
*) next
;
194 #endif /* ALCONTEXT_H */