Integrating FAudio, a reimplementation of XAudio2

Ethan Lee flibitijibibo at flibitijibibo.com
Fri Oct 19 22:58:15 CDT 2018


 >That's effectively true with the global allocators already, in the 
sense that setting one set of allocators in one part of the application, 
and later a different set of allocators in another part is unlikely to 
end well

This is a really good point, and is the main reason I want to come up 
with something better. I have one last idea, and it's something I do for 
FNA every now and then: A formalized extension.

In this case it would be something like "CustomAllocatorEXT", where all 
the construction entry points get a new overload like 
"FAudioCreateWithCustomAllocatorEXT", which is the same as the official 
FAudioCreate but with added parameters for function pointer types like 
FAudioCustomMallocEXT, and those would get stored in each context. The 
nice thing about everything being tied together in an extension is that 
I can document in big giant letters "DO NOT MIX ALLOCATORS" and avoid 
both the global variable safety issue as well as the malloc/free 
mismatch problems.

It also avoids possible breakage of the existing APIs, which is 
something we now have to consider as of FNA 18.10's release. I've been 
pretty lenient with breakages in the past for stuff like MojoShader and 
Theorafile since those are used by pretty much nobody but myself and 
Ryan, and even for the small FNA community that's managed to pop up on 
occasion.

-Ethan

On 10/19/18 22:42, Henri Verbeet wrote:
> On Sat, 20 Oct 2018 at 04:35, Ethan Lee <flibitijibibo at flibitijibibo.com> wrote:
>> The biggest problem is that there are _loads_ of entry points that
>> aren't necessarily coupled with one another - the main ones are
>> XAudio2Create, XACT3CreateEngine, CreateReverb, CreateVolumeMeter, and
>> CreateFX, all of which are technically supposed to be decoupled from one
>> another even though they all directly interact with each other and
>> nothing outside of this subsystem of DirectX. The famous "we're totally
>> decoupled except for the part where we're not" scenario. So in reality,
>> you're not setting 1 allocator, you're setting up to 5:
>>
> Personally, I don't have an issue with that. I.e., I think providing
> allocators to each entry point that needs them would be fine.
>
>> You might be thinking we could add the callback system to every
>> function, but keep in mind that the allocators in some parts should be
>> the same as in others, or malloc/free mismatches can occur. Admittedly
>> it's "some" and not "all", but the fact that it's ambiguous is what
>> makes it kind of dangerous to wield (IMO). Even worse, there's
>> situations like AudioEngine_Initialize that takes in an optional XAudio2
>> parameter:
>>
>> https://github.com/FNA-XNA/FAudio/blob/2fdfc193940a1aa9a89f84ce46bf7ff84280ae1b/src/FACT.h#L109
>>
>> So then some questions come up along the lines of "which allocator do we
>> use, the XACT3 allocator all the time, or the XAudio2 allocator if we
>> provide that (since the engine may have already allocated some stuff),
>> or do we allow an XACT3 with allocator A and a custom XAudio2 with
>> allocator B, and try to support both at the same time," and that's just
>> the interaction between XACT and XAudio; there are potential conflicts
>> with XAPO as well because the APO could be using allocator A but XAudio
>> expects allocator B when reading RegistrationProprties, and that's not
>> factoring in what could happen with custom XAudio2 voices you can set on
>> XACT3 voices with custom XAPOs attached... you get the idea.
>>
>> The global allocator definitely feels primitive and clunky, but I don't
>> know if I have it in me to figure out the above...
>>
> Yeah, you'd have to resolve that somehow. Ideally that would mean
> carefully thinking about which kinds of interactions make sense, but
> the easy way out would be to define it away by saying something along
> the lines of "Using objects created with incompatible allocators
> together results in undefined behaviour". That's effectively true with
> the global allocators already, in the sense that setting one set of
> allocators in one part of the application, and later a different set
> of allocators in another part is unlikely to end well; where it makes
> a difference is for objects that don't interact.
>
> In practice, I'd expect Wine to always use the same allocators, so the
> argument is perhaps somewhat academic. From an API-design point of
> view though, it seems better to try to get it right the first time
> than to have to fix it later.
>




More information about the wine-devel mailing list