Repository: google/filament
File: filament/backend/include/private/backend/Driver.h (C/C++)

Code before:
class ConcreteDispatcher;
class Dispatcher;
class CommandStream;

class Driver {
public:
    virtual ~Driver() noexcept;

    static size_t getElementTypeSize(ElementType type) noexcept;

    // called from the main thread (NOT the render-thread) at various intervals, this
    // is where the driver can execute user callbacks.
    virtual void purge() noexcept = 0;

    virtual ShaderModel getShaderModel() const noexcept = 0;

    // The shader language used for shaders for this driver, used to inform matdbg.
    //
    // For OpenGL, this distinguishes whether the driver's shaders are powered by ESSL1 or ESSL3.
    // This information is used by matdbg to display the correct shader code to the web UI and patch
    // the correct chunk when rebuilding shaders live.
    //
    // Metal shaders can either be MSL or Metal libraries, but at time of writing, matdbg can only
    // interface with MSL.
    virtual utils::FixedCapacityVector<ShaderLanguage> getShaderLanguage(
            PreferredShaderLanguage preferredLanguage) const noexcept = 0;

    // Returns the dispatcher. This is only called once during initialization of the CommandStream,
    // so it doesn't matter that it's virtual.
    virtual Dispatcher getDispatcher() const noexcept = 0;

    // called from CommandStream::execute on the render-thread
    // the fn function will execute a batch of driver commands
    // this gives the driver a chance to wrap their execution in a meaningful manner
    // the default implementation simply calls fn
    virtual void execute(std::function<void(void)> const& fn);

    // This is called on debug build, or when enabled manually on the backend thread side.
    virtual void debugCommandBegin(CommandStream* cmds,
            bool synchronous, const char* methodName) noexcept = 0;

    virtual void debugCommandEnd(CommandStream* cmds,
            bool synchronous, const char* methodName) noexcept = 0;

    /*
     * Asynchronous calls here only to provide a type to CommandStream. They must be non-virtual
     * so that calling the concrete implementation won't go through a vtable.
     *
     * Synchronous calls are virtual and are called directly by CommandStream.
     */


Review comment (suggestion):
use `ShaderLanguage` here, and document that's only hint. If the backend supports the asked prefered language, it must appear first in the list.

Code after:
class ConcreteDispatcher;
class Dispatcher;
class CommandStream;

class Driver {
public:
    virtual ~Driver() noexcept;

    static size_t getElementTypeSize(ElementType type) noexcept;

    // called from the main thread (NOT the render-thread) at various intervals, this
    // is where the driver can execute user callbacks.
    virtual void purge() noexcept = 0;

    virtual ShaderModel getShaderModel() const noexcept = 0;

    // The shader languages used for shaders for this driver in order of preference, used to inform
    // matdbg.
    //
    // The `preferredLanguage` is only a hint. If the backend supports it, it will appear first in
    // the list.
    //
    // For OpenGL, this distinguishes whether the driver's shaders are powered by ESSL1 or ESSL3.
    // This information is used by matdbg to display the correct shader code to the web UI and patch
    // the correct chunk when rebuilding shaders live.
    //
    // Metal shaders can either be MSL or Metal libraries, but at time of writing, matdbg can only
    // interface with MSL.
    virtual utils::FixedCapacityVector<ShaderLanguage> getShaderLanguages(
            ShaderLanguage preferredLanguage) const noexcept = 0;

    // Returns the dispatcher. This is only called once during initialization of the CommandStream,
    // so it doesn't matter that it's virtual.
    virtual Dispatcher getDispatcher() const noexcept = 0;

    // called from CommandStream::execute on the render-thread
    // the fn function will execute a batch of driver commands
    // this gives the driver a chance to wrap their execution in a meaningful manner
    // the default implementation simply calls fn
    virtual void execute(std::function<void(void)> const& fn);

    // This is called on debug build, or when enabled manually on the backend thread side.
    virtual void debugCommandBegin(CommandStream* cmds,
            bool synchronous, const char* methodName) noexcept = 0;

    virtual void debugCommandEnd(CommandStream* cmds,
            bool synchronous, const char* methodName) noexcept = 0;

    /*
     * Asynchronous calls here only to provide a type to CommandStream. They must be non-virtual
     * so that calling the concrete implementation won't go through a vtable.