969 lines
38 KiB
C++
969 lines
38 KiB
C++
/*
|
|
* Copyright (C) 2015 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef TNT_FILAMENT_ENGINE_H
|
|
#define TNT_FILAMENT_ENGINE_H
|
|
|
|
#include <filament/FilamentAPI.h>
|
|
|
|
#include <backend/DriverEnums.h>
|
|
#include <backend/Platform.h>
|
|
|
|
#include <utils/compiler.h>
|
|
#include <utils/Invocable.h>
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
namespace utils {
|
|
class Entity;
|
|
class EntityManager;
|
|
class JobSystem;
|
|
} // namespace utils
|
|
|
|
namespace filament {
|
|
|
|
class BufferObject;
|
|
class Camera;
|
|
class ColorGrading;
|
|
class DebugRegistry;
|
|
class Fence;
|
|
class IndexBuffer;
|
|
class SkinningBuffer;
|
|
class IndirectLight;
|
|
class Material;
|
|
class MaterialInstance;
|
|
class MorphTargetBuffer;
|
|
class Renderer;
|
|
class RenderTarget;
|
|
class Scene;
|
|
class Skybox;
|
|
class Stream;
|
|
class SwapChain;
|
|
class Texture;
|
|
class VertexBuffer;
|
|
class View;
|
|
class InstanceBuffer;
|
|
|
|
class LightManager;
|
|
class RenderableManager;
|
|
class TransformManager;
|
|
|
|
#ifndef FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB
|
|
# define FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB 3
|
|
#endif
|
|
|
|
#ifndef FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB
|
|
# define FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB 2
|
|
#endif
|
|
|
|
#ifndef FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB
|
|
# define FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB 1
|
|
#endif
|
|
|
|
#ifndef FILAMENT_COMMAND_BUFFER_SIZE_IN_MB
|
|
# define FILAMENT_COMMAND_BUFFER_SIZE_IN_MB (FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB * 3)
|
|
#endif
|
|
|
|
/**
|
|
* Engine is filament's main entry-point.
|
|
*
|
|
* An Engine instance main function is to keep track of all resources created by the user and
|
|
* manage the rendering thread as well as the hardware renderer.
|
|
*
|
|
* To use filament, an Engine instance must be created first:
|
|
*
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
* #include <filament/Engine.h>
|
|
* using namespace filament;
|
|
*
|
|
* Engine* engine = Engine::create();
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
*
|
|
* Engine essentially represents (or is associated to) a hardware context
|
|
* (e.g. an OpenGL ES context).
|
|
*
|
|
* Rendering typically happens in an operating system's window (which can be full screen), such
|
|
* window is managed by a filament.Renderer.
|
|
*
|
|
* A typical filament render loop looks like this:
|
|
*
|
|
*
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
* #include <filament/Engine.h>
|
|
* #include <filament/Renderer.h>
|
|
* #include <filament/Scene.h>
|
|
* #include <filament/View.h>
|
|
* using namespace filament;
|
|
*
|
|
* Engine* engine = Engine::create();
|
|
* SwapChain* swapChain = engine->createSwapChain(nativeWindow);
|
|
* Renderer* renderer = engine->createRenderer();
|
|
* Scene* scene = engine->createScene();
|
|
* View* view = engine->createView();
|
|
*
|
|
* view->setScene(scene);
|
|
*
|
|
* do {
|
|
* // typically we wait for VSYNC and user input events
|
|
* if (renderer->beginFrame(swapChain)) {
|
|
* renderer->render(view);
|
|
* renderer->endFrame();
|
|
* }
|
|
* } while (!quit);
|
|
*
|
|
* engine->destroy(view);
|
|
* engine->destroy(scene);
|
|
* engine->destroy(renderer);
|
|
* engine->destroy(swapChain);
|
|
* Engine::destroy(&engine); // clears engine*
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
*
|
|
* Resource Tracking
|
|
* =================
|
|
*
|
|
* Each Engine instance keeps track of all objects created by the user, such as vertex and index
|
|
* buffers, lights, cameras, etc...
|
|
* The user is expected to free those resources, however, leaked resources are freed when the
|
|
* engine instance is destroyed and a warning is emitted in the console.
|
|
*
|
|
* Thread safety
|
|
* =============
|
|
*
|
|
* An Engine instance is not thread-safe. The implementation makes no attempt to synchronize
|
|
* calls to an Engine instance methods.
|
|
* If multi-threading is needed, synchronization must be external.
|
|
*
|
|
* Multi-threading
|
|
* ===============
|
|
*
|
|
* When created, the Engine instance starts a render thread as well as multiple worker threads,
|
|
* these threads have an elevated priority appropriate for rendering, based on the platform's
|
|
* best practices. The number of worker threads depends on the platform and is automatically
|
|
* chosen for best performance.
|
|
*
|
|
* On platforms with asymmetric cores (e.g. ARM's Big.Little), Engine makes some educated guesses
|
|
* as to which cores to use for the render thread and worker threads. For example, it'll try to
|
|
* keep an OpenGL ES thread on a Big core.
|
|
*
|
|
* Swap Chains
|
|
* ===========
|
|
*
|
|
* A swap chain represents an Operating System's *native* renderable surface. Typically it's a window
|
|
* or a view. Because a SwapChain is initialized from a native object, it is given to filament
|
|
* as a `void*`, which must be of the proper type for each platform filament is running on.
|
|
*
|
|
* @see SwapChain
|
|
*
|
|
*
|
|
* @see Renderer
|
|
*/
|
|
class UTILS_PUBLIC Engine {
|
|
struct BuilderDetails;
|
|
public:
|
|
using Platform = backend::Platform;
|
|
using Backend = backend::Backend;
|
|
using DriverConfig = backend::Platform::DriverConfig;
|
|
using FeatureLevel = backend::FeatureLevel;
|
|
using StereoscopicType = backend::StereoscopicType;
|
|
|
|
/**
|
|
* Config is used to define the memory footprint used by the engine, such as the
|
|
* command buffer size. Config can be used to customize engine requirements based
|
|
* on the applications needs.
|
|
*
|
|
* .perRenderPassArenaSizeMB (default: 3 MiB)
|
|
* +--------------------------+
|
|
* | |
|
|
* | .perFrameCommandsSizeMB |
|
|
* | (default 2 MiB) |
|
|
* | |
|
|
* +--------------------------+
|
|
* | (froxel, etc...) |
|
|
* +--------------------------+
|
|
*
|
|
*
|
|
* .commandBufferSizeMB (default 3MiB)
|
|
* +--------------------------+
|
|
* | .minCommandBufferSizeMB |
|
|
* +--------------------------+
|
|
* | .minCommandBufferSizeMB |
|
|
* +--------------------------+
|
|
* | .minCommandBufferSizeMB |
|
|
* +--------------------------+
|
|
* : :
|
|
* : :
|
|
*
|
|
*/
|
|
struct Config {
|
|
/**
|
|
* Size in MiB of the low-level command buffer arena.
|
|
*
|
|
* Each new command buffer is allocated from here. If this buffer is too small the program
|
|
* might terminate or rendering errors might occur.
|
|
*
|
|
* This is typically set to minCommandBufferSizeMB * 3, so that up to 3 frames can be
|
|
* batched-up at once.
|
|
*
|
|
* This value affects the application's memory usage.
|
|
*/
|
|
uint32_t commandBufferSizeMB = FILAMENT_COMMAND_BUFFER_SIZE_IN_MB;
|
|
|
|
|
|
/**
|
|
* Size in MiB of the per-frame data arena.
|
|
*
|
|
* This is the main arena used for allocations when preparing a frame.
|
|
* e.g.: Froxel data and high-level commands are allocated from this arena.
|
|
*
|
|
* If this size is too small, the program will abort on debug builds and have undefined
|
|
* behavior otherwise.
|
|
*
|
|
* This value affects the application's memory usage.
|
|
*/
|
|
uint32_t perRenderPassArenaSizeMB = FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB;
|
|
|
|
|
|
/**
|
|
* Size in MiB of the backend's handle arena.
|
|
*
|
|
* Backends will fallback to slower heap-based allocations when running out of space and
|
|
* log this condition.
|
|
*
|
|
* If 0, then the default value for the given platform is used
|
|
*
|
|
* This value affects the application's memory usage.
|
|
*/
|
|
uint32_t driverHandleArenaSizeMB = 0;
|
|
|
|
|
|
/**
|
|
* Minimum size in MiB of a low-level command buffer.
|
|
*
|
|
* This is how much space is guaranteed to be available for low-level commands when a new
|
|
* buffer is allocated. If this is too small, the engine might have to stall to wait for
|
|
* more space to become available, this situation is logged.
|
|
*
|
|
* This value does not affect the application's memory usage.
|
|
*/
|
|
uint32_t minCommandBufferSizeMB = FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB;
|
|
|
|
|
|
/**
|
|
* Size in MiB of the per-frame high level command buffer.
|
|
*
|
|
* This buffer is related to the number of draw calls achievable within a frame, if it is
|
|
* too small, the program will abort on debug builds and have undefined behavior otherwise.
|
|
*
|
|
* It is allocated from the 'per-render-pass arena' above. Make sure that at least 1 MiB is
|
|
* left in the per-render-pass arena when deciding the size of this buffer.
|
|
*
|
|
* This value does not affect the application's memory usage.
|
|
*/
|
|
uint32_t perFrameCommandsSizeMB = FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB;
|
|
|
|
/**
|
|
* Number of threads to use in Engine's JobSystem.
|
|
*
|
|
* Engine uses a utils::JobSystem to carry out paralleization of Engine workloads. This
|
|
* value sets the number of threads allocated for JobSystem. Configuring this value can be
|
|
* helpful in CPU-constrained environments where too many threads can cause contention of
|
|
* CPU and reduce performance.
|
|
*
|
|
* The default value is 0, which implies that the Engine will use a heuristic to determine
|
|
* the number of threads to use.
|
|
*/
|
|
uint32_t jobSystemThreadCount = 0;
|
|
|
|
/*
|
|
* Number of most-recently destroyed textures to track for use-after-free.
|
|
*
|
|
* This will cause the backend to throw an exception when a texture is freed but still bound
|
|
* to a SamplerGroup and used in a draw call. 0 disables completely.
|
|
*
|
|
* Currently only respected by the Metal backend.
|
|
*/
|
|
size_t textureUseAfterFreePoolSize = 0;
|
|
|
|
/**
|
|
* Set to `true` to forcibly disable parallel shader compilation in the backend.
|
|
* Currently only honored by the GL and Metal backends.
|
|
*/
|
|
bool disableParallelShaderCompile = false;
|
|
|
|
/*
|
|
* The type of technique for stereoscopic rendering.
|
|
*
|
|
* This setting determines the algorithm used when stereoscopic rendering is enabled. This
|
|
* decision applies to the entire Engine for the lifetime of the Engine. E.g., multiple
|
|
* Views created from the Engine must use the same stereoscopic type.
|
|
*
|
|
* Each view can enable stereoscopic rendering via the StereoscopicOptions::enable flag.
|
|
*
|
|
* @see View::setStereoscopicOptions
|
|
*/
|
|
StereoscopicType stereoscopicType = StereoscopicType::INSTANCED;
|
|
|
|
/*
|
|
* The number of eyes to render when stereoscopic rendering is enabled. Supported values are
|
|
* between 1 and Engine::getMaxStereoscopicEyes() (inclusive).
|
|
*
|
|
* @see View::setStereoscopicOptions
|
|
* @see Engine::getMaxStereoscopicEyes
|
|
*/
|
|
uint8_t stereoscopicEyeCount = 2;
|
|
|
|
/*
|
|
* @deprecated This value is no longer used.
|
|
*/
|
|
uint32_t resourceAllocatorCacheSizeMB = 64;
|
|
|
|
/*
|
|
* This value determines for how many frames are texture entries kept in the cache.
|
|
*/
|
|
uint32_t resourceAllocatorCacheMaxAge = 2;
|
|
|
|
/*
|
|
* Disable backend handles use-after-free checks.
|
|
*/
|
|
bool disableHandleUseAfterFreeCheck = false;
|
|
};
|
|
|
|
|
|
#if UTILS_HAS_THREADING
|
|
using CreateCallback = void(void* UTILS_NULLABLE user, void* UTILS_NONNULL token);
|
|
#endif
|
|
|
|
/**
|
|
* Engine::Builder is used to create a new filament Engine.
|
|
*/
|
|
class Builder : public BuilderBase<BuilderDetails> {
|
|
friend struct BuilderDetails;
|
|
friend class FEngine;
|
|
public:
|
|
Builder() noexcept;
|
|
Builder(Builder const& rhs) noexcept;
|
|
Builder(Builder&& rhs) noexcept;
|
|
~Builder() noexcept;
|
|
Builder& operator=(Builder const& rhs) noexcept;
|
|
Builder& operator=(Builder&& rhs) noexcept;
|
|
|
|
/**
|
|
* @param backend Which driver backend to use
|
|
* @return A reference to this Builder for chaining calls.
|
|
*/
|
|
Builder& backend(Backend backend) noexcept;
|
|
|
|
/**
|
|
* @param platform A pointer to an object that implements Platform. If this is
|
|
* provided, then this object is used to create the hardware context
|
|
* and expose platform features to it.
|
|
*
|
|
* If not provided (or nullptr is used), an appropriate Platform
|
|
* is created automatically.
|
|
*
|
|
* All methods of this interface are called from filament's
|
|
* render thread, which is different from the main thread.
|
|
*
|
|
* The lifetime of \p platform must exceed the lifetime of
|
|
* the Engine object.
|
|
*
|
|
* @return A reference to this Builder for chaining calls.
|
|
*/
|
|
Builder& platform(Platform* UTILS_NULLABLE platform) noexcept;
|
|
|
|
/**
|
|
* @param config A pointer to optional parameters to specify memory size
|
|
* configuration options. If nullptr, then defaults used.
|
|
*
|
|
* @return A reference to this Builder for chaining calls.
|
|
*/
|
|
Builder& config(const Config* UTILS_NULLABLE config) noexcept;
|
|
|
|
/**
|
|
* @param sharedContext A platform-dependant context used as a shared context
|
|
* when creating filament's internal context.
|
|
*
|
|
* @return A reference to this Builder for chaining calls.
|
|
*/
|
|
Builder& sharedContext(void* UTILS_NULLABLE sharedContext) noexcept;
|
|
|
|
/**
|
|
* @param featureLevel The feature level at which initialize Filament.
|
|
* @return A reference to this Builder for chaining calls.
|
|
*/
|
|
Builder& featureLevel(FeatureLevel featureLevel) noexcept;
|
|
|
|
/**
|
|
* Warning: This is an experimental API. See Engine::setPaused(bool) for caveats.
|
|
*
|
|
* @param paused Whether to start the rendering thread paused.
|
|
* @return A reference to this Builder for chaining calls.
|
|
*/
|
|
Builder& paused(bool paused) noexcept;
|
|
|
|
#if UTILS_HAS_THREADING
|
|
/**
|
|
* Creates the filament Engine asynchronously.
|
|
*
|
|
* @param callback Callback called once the engine is initialized and it is safe to
|
|
* call Engine::getEngine().
|
|
*/
|
|
void build(utils::Invocable<void(void* UTILS_NONNULL token)>&& callback) const;
|
|
#endif
|
|
|
|
/**
|
|
* Creates an instance of Engine.
|
|
*
|
|
* @return A pointer to the newly created Engine, or nullptr if the Engine couldn't be
|
|
* created.
|
|
* nullptr if the GPU driver couldn't be initialized, for instance if it doesn't
|
|
* support the right version of OpenGL or OpenGL ES.
|
|
*
|
|
* @exception utils::PostConditionPanic can be thrown if there isn't enough memory to
|
|
* allocate the command buffer. If exceptions are disabled, this condition if
|
|
* fatal and this function will abort.
|
|
*/
|
|
Engine* UTILS_NULLABLE build() const;
|
|
};
|
|
|
|
/**
|
|
* Backward compatibility helper to create an Engine.
|
|
* @see Builder
|
|
*/
|
|
static inline Engine* UTILS_NULLABLE create(Backend backend = Backend::DEFAULT,
|
|
Platform* UTILS_NULLABLE platform = nullptr,
|
|
void* UTILS_NULLABLE sharedContext = nullptr,
|
|
const Config* UTILS_NULLABLE config = nullptr) {
|
|
return Engine::Builder()
|
|
.backend(backend)
|
|
.platform(platform)
|
|
.sharedContext(sharedContext)
|
|
.config(config)
|
|
.build();
|
|
}
|
|
|
|
|
|
#if UTILS_HAS_THREADING
|
|
/**
|
|
* Backward compatibility helper to create an Engine asynchronously.
|
|
* @see Builder
|
|
*/
|
|
static inline void createAsync(CreateCallback callback,
|
|
void* UTILS_NULLABLE user,
|
|
Backend backend = Backend::DEFAULT,
|
|
Platform* UTILS_NULLABLE platform = nullptr,
|
|
void* UTILS_NULLABLE sharedContext = nullptr,
|
|
const Config* UTILS_NULLABLE config = nullptr) {
|
|
Engine::Builder()
|
|
.backend(backend)
|
|
.platform(platform)
|
|
.sharedContext(sharedContext)
|
|
.config(config)
|
|
.build([callback, user](void* UTILS_NONNULL token) {
|
|
callback(user, token);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Retrieve an Engine* from createAsync(). This must be called from the same thread than
|
|
* Engine::createAsync() was called from.
|
|
*
|
|
* @param token An opaque token given in the createAsync() callback function.
|
|
*
|
|
* @return A pointer to the newly created Engine, or nullptr if the Engine couldn't be created.
|
|
*
|
|
* @exception utils::PostConditionPanic can be thrown if there isn't enough memory to
|
|
* allocate the command buffer. If exceptions are disabled, this condition if fatal and
|
|
* this function will abort.
|
|
*/
|
|
static Engine* UTILS_NULLABLE getEngine(void* UTILS_NONNULL token);
|
|
#endif
|
|
|
|
|
|
/**
|
|
* Destroy the Engine instance and all associated resources.
|
|
*
|
|
* Engine.destroy() should be called last and after all other resources have been destroyed,
|
|
* it ensures all filament resources are freed.
|
|
*
|
|
* Destroy performs the following tasks:
|
|
* 1. Destroy all internal software and hardware resources.
|
|
* 2. Free all user allocated resources that are not already destroyed and logs a warning.
|
|
* This indicates a "leak" in the user's code.
|
|
* 3. Terminate the rendering engine's thread.
|
|
*
|
|
* @param engine A pointer to the filament.Engine* to be destroyed.
|
|
* \p engine is cleared upon return.
|
|
*
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
* #include <filament/Engine.h>
|
|
* using namespace filament;
|
|
*
|
|
* Engine* engine = Engine::create();
|
|
* Engine::destroy(&engine); // clears engine*
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
*
|
|
* \remark
|
|
* This method is thread-safe.
|
|
*/
|
|
static void destroy(Engine* UTILS_NULLABLE* UTILS_NULLABLE engine);
|
|
|
|
/**
|
|
* Destroy the Engine instance and all associated resources.
|
|
*
|
|
* Engine.destroy() should be called last and after all other resources have been destroyed,
|
|
* it ensures all filament resources are freed.
|
|
*
|
|
* Destroy performs the following tasks:
|
|
* 1. Destroy all internal software and hardware resources.
|
|
* 2. Free all user allocated resources that are not already destroyed and logs a warning.
|
|
* This indicates a "leak" in the user's code.
|
|
* 3. Terminate the rendering engine's thread.
|
|
*
|
|
* @param engine A pointer to the filament.Engine to be destroyed.
|
|
*
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
* #include <filament/Engine.h>
|
|
* using namespace filament;
|
|
*
|
|
* Engine* engine = Engine::create();
|
|
* Engine::destroy(engine);
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
*
|
|
* \remark
|
|
* This method is thread-safe.
|
|
*/
|
|
static void destroy(Engine* UTILS_NULLABLE engine);
|
|
|
|
/**
|
|
* Query the feature level supported by the selected backend.
|
|
*
|
|
* A specific feature level needs to be set before the corresponding features can be used.
|
|
*
|
|
* @return FeatureLevel supported the selected backend.
|
|
* @see setActiveFeatureLevel
|
|
*/
|
|
FeatureLevel getSupportedFeatureLevel() const noexcept;
|
|
|
|
/**
|
|
* Activate all features of a given feature level. If an explicit feature level is not specified
|
|
* at Engine initialization time via Builder::featureLevel, the default feature level is
|
|
* FeatureLevel::FEATURE_LEVEL_0 on devices not compatible with GLES 3.0; otherwise, the default
|
|
* is FeatureLevel::FEATURE_LEVEL_1. The selected feature level must not be higher than the
|
|
* value returned by getActiveFeatureLevel() and it's not possible lower the active feature
|
|
* level. Additionally, it is not possible to modify the feature level at all if the Engine was
|
|
* initialized at FeatureLevel::FEATURE_LEVEL_0.
|
|
*
|
|
* @param featureLevel the feature level to activate. If featureLevel is lower than
|
|
* getActiveFeatureLevel(), the current (higher) feature level is kept. If
|
|
* featureLevel is higher than getSupportedFeatureLevel(), or if the engine
|
|
* was initialized at feature level 0, an exception is thrown, or the
|
|
* program is terminated if exceptions are disabled.
|
|
*
|
|
* @return the active feature level.
|
|
*
|
|
* @see Builder::featureLevel
|
|
* @see getSupportedFeatureLevel
|
|
* @see getActiveFeatureLevel
|
|
*/
|
|
FeatureLevel setActiveFeatureLevel(FeatureLevel featureLevel);
|
|
|
|
/**
|
|
* Returns the currently active feature level.
|
|
* @return currently active feature level
|
|
* @see getSupportedFeatureLevel
|
|
* @see setActiveFeatureLevel
|
|
*/
|
|
FeatureLevel getActiveFeatureLevel() const noexcept;
|
|
|
|
/**
|
|
* Queries the maximum number of GPU instances that Filament creates when automatic instancing
|
|
* is enabled. This value is also the limit for the number of transforms that can be stored in
|
|
* an InstanceBuffer. This value may depend on the device and platform, but will remain constant
|
|
* during the lifetime of this Engine.
|
|
*
|
|
* This value does not apply when using the instances(size_t) method on
|
|
* RenderableManager::Builder.
|
|
*
|
|
* @return the number of max automatic instances
|
|
* @see setAutomaticInstancingEnabled
|
|
* @see RenderableManager::Builder::instances(size_t)
|
|
* @see RenderableManager::Builder::instances(size_t, InstanceBuffer*)
|
|
*/
|
|
size_t getMaxAutomaticInstances() const noexcept;
|
|
|
|
/**
|
|
* Queries the device and platform for support of the given stereoscopic type.
|
|
*
|
|
* @return true if the given stereo rendering is supported, false otherwise
|
|
* @see View::setStereoscopicOptions
|
|
*/
|
|
bool isStereoSupported(StereoscopicType stereoscopicType) const noexcept;
|
|
|
|
/**
|
|
* Retrieves the configuration settings of this Engine.
|
|
*
|
|
* This method returns the configuration object that was supplied to the Engine's
|
|
* Builder::config method during the creation of this Engine. If the Builder::config method was
|
|
* not explicitly called (or called with nullptr), this method returns the default configuration
|
|
* settings.
|
|
*
|
|
* @return a Config object with this Engine's configuration
|
|
* @see Builder::config
|
|
*/
|
|
const Config& getConfig() const noexcept;
|
|
|
|
/**
|
|
* Returns the maximum number of stereoscopic eyes supported by Filament. The actual number of
|
|
* eyes rendered is set at Engine creation time with the Engine::Config::stereoscopicEyeCount
|
|
* setting.
|
|
*
|
|
* @return the max number of stereoscopic eyes supported
|
|
* @see Engine::Config::stereoscopicEyeCount
|
|
*/
|
|
static size_t getMaxStereoscopicEyes() noexcept;
|
|
|
|
/**
|
|
* @return EntityManager used by filament
|
|
*/
|
|
utils::EntityManager& getEntityManager() noexcept;
|
|
|
|
/**
|
|
* @return RenderableManager reference
|
|
*/
|
|
RenderableManager& getRenderableManager() noexcept;
|
|
|
|
/**
|
|
* @return LightManager reference
|
|
*/
|
|
LightManager& getLightManager() noexcept;
|
|
|
|
/**
|
|
* @return TransformManager reference
|
|
*/
|
|
TransformManager& getTransformManager() noexcept;
|
|
|
|
/**
|
|
* Helper to enable accurate translations.
|
|
* If you need this Engine to handle a very large world space, one way to achieve this
|
|
* automatically is to enable accurate translations in the TransformManager. This helper
|
|
* provides a convenient way of doing that.
|
|
* This is typically called once just after creating the Engine.
|
|
*/
|
|
void enableAccurateTranslations() noexcept;
|
|
|
|
/**
|
|
* Enables or disables automatic instancing of render primitives. Instancing of render
|
|
* primitives can greatly reduce CPU overhead but requires the instanced primitives to be
|
|
* identical (i.e. use the same geometry) and use the same MaterialInstance. If it is known
|
|
* that the scene doesn't contain any identical primitives, automatic instancing can have some
|
|
* overhead and it is then best to disable it.
|
|
*
|
|
* Disabled by default.
|
|
*
|
|
* @param enable true to enable, false to disable automatic instancing.
|
|
*
|
|
* @see RenderableManager
|
|
* @see MaterialInstance
|
|
*/
|
|
void setAutomaticInstancingEnabled(bool enable) noexcept;
|
|
|
|
/**
|
|
* @return true if automatic instancing is enabled, false otherwise.
|
|
* @see setAutomaticInstancingEnabled
|
|
*/
|
|
bool isAutomaticInstancingEnabled() const noexcept;
|
|
|
|
/**
|
|
* Creates a SwapChain from the given Operating System's native window handle.
|
|
*
|
|
* @param nativeWindow An opaque native window handle. e.g.: on Android this is an
|
|
* `ANativeWindow*`.
|
|
* @param flags One or more configuration flags as defined in `SwapChain`.
|
|
*
|
|
* @return A pointer to the newly created SwapChain.
|
|
*
|
|
* @see Renderer.beginFrame()
|
|
*/
|
|
SwapChain* UTILS_NONNULL createSwapChain(void* UTILS_NULLABLE nativeWindow, uint64_t flags = 0) noexcept;
|
|
|
|
|
|
/**
|
|
* Creates a headless SwapChain.
|
|
*
|
|
* @param width Width of the drawing buffer in pixels.
|
|
* @param height Height of the drawing buffer in pixels.
|
|
* @param flags One or more configuration flags as defined in `SwapChain`.
|
|
*
|
|
* @return A pointer to the newly created SwapChain.
|
|
*
|
|
* @see Renderer.beginFrame()
|
|
*/
|
|
SwapChain* UTILS_NONNULL createSwapChain(uint32_t width, uint32_t height, uint64_t flags = 0) noexcept;
|
|
|
|
/**
|
|
* Creates a renderer associated to this engine.
|
|
*
|
|
* A Renderer is intended to map to a *window* on screen.
|
|
*
|
|
* @return A pointer to the newly created Renderer.
|
|
*/
|
|
Renderer* UTILS_NONNULL createRenderer() noexcept;
|
|
|
|
/**
|
|
* Creates a View.
|
|
*
|
|
* @return A pointer to the newly created View.
|
|
*/
|
|
View* UTILS_NONNULL createView() noexcept;
|
|
|
|
/**
|
|
* Creates a Scene.
|
|
*
|
|
* @return A pointer to the newly created Scene.
|
|
*/
|
|
Scene* UTILS_NONNULL createScene() noexcept;
|
|
|
|
/**
|
|
* Creates a Camera component.
|
|
*
|
|
* @param entity Entity to add the camera component to.
|
|
* @return A pointer to the newly created Camera.
|
|
*/
|
|
Camera* UTILS_NONNULL createCamera(utils::Entity entity) noexcept;
|
|
|
|
/**
|
|
* Returns the Camera component of the given entity.
|
|
*
|
|
* @param entity An entity.
|
|
* @return A pointer to the Camera component for this entity or nullptr if the entity didn't
|
|
* have a Camera component. The pointer is valid until destroyCameraComponent()
|
|
* is called or the entity itself is destroyed.
|
|
*/
|
|
Camera* UTILS_NULLABLE getCameraComponent(utils::Entity entity) noexcept;
|
|
|
|
/**
|
|
* Destroys the Camera component associated with the given entity.
|
|
*
|
|
* @param entity An entity.
|
|
*/
|
|
void destroyCameraComponent(utils::Entity entity) noexcept;
|
|
|
|
/**
|
|
* Creates a Fence.
|
|
*
|
|
* @return A pointer to the newly created Fence.
|
|
*/
|
|
Fence* UTILS_NONNULL createFence() noexcept;
|
|
|
|
bool destroy(const BufferObject* UTILS_NULLABLE p); //!< Destroys a BufferObject object.
|
|
bool destroy(const VertexBuffer* UTILS_NULLABLE p); //!< Destroys an VertexBuffer object.
|
|
bool destroy(const Fence* UTILS_NULLABLE p); //!< Destroys a Fence object.
|
|
bool destroy(const IndexBuffer* UTILS_NULLABLE p); //!< Destroys an IndexBuffer object.
|
|
bool destroy(const SkinningBuffer* UTILS_NULLABLE p); //!< Destroys a SkinningBuffer object.
|
|
bool destroy(const MorphTargetBuffer* UTILS_NULLABLE p); //!< Destroys a MorphTargetBuffer object.
|
|
bool destroy(const IndirectLight* UTILS_NULLABLE p); //!< Destroys an IndirectLight object.
|
|
|
|
/**
|
|
* Destroys a Material object
|
|
* @param p the material object to destroy
|
|
* @attention All MaterialInstance of the specified material must be destroyed before
|
|
* destroying it.
|
|
* @exception utils::PreConditionPanic is thrown if some MaterialInstances remain.
|
|
* no-op if exceptions are disabled and some MaterialInstances remain.
|
|
*/
|
|
bool destroy(const Material* UTILS_NULLABLE p);
|
|
bool destroy(const MaterialInstance* UTILS_NULLABLE p); //!< Destroys a MaterialInstance object.
|
|
bool destroy(const Renderer* UTILS_NULLABLE p); //!< Destroys a Renderer object.
|
|
bool destroy(const Scene* UTILS_NULLABLE p); //!< Destroys a Scene object.
|
|
bool destroy(const Skybox* UTILS_NULLABLE p); //!< Destroys a SkyBox object.
|
|
bool destroy(const ColorGrading* UTILS_NULLABLE p); //!< Destroys a ColorGrading object.
|
|
bool destroy(const SwapChain* UTILS_NULLABLE p); //!< Destroys a SwapChain object.
|
|
bool destroy(const Stream* UTILS_NULLABLE p); //!< Destroys a Stream object.
|
|
bool destroy(const Texture* UTILS_NULLABLE p); //!< Destroys a Texture object.
|
|
bool destroy(const RenderTarget* UTILS_NULLABLE p); //!< Destroys a RenderTarget object.
|
|
bool destroy(const View* UTILS_NULLABLE p); //!< Destroys a View object.
|
|
bool destroy(const InstanceBuffer* UTILS_NULLABLE p); //!< Destroys an InstanceBuffer object.
|
|
void destroy(utils::Entity e); //!< Destroys all filament-known components from this entity
|
|
|
|
bool isValid(const BufferObject* UTILS_NULLABLE p); //!< Tells whether a BufferObject object is valid
|
|
bool isValid(const VertexBuffer* UTILS_NULLABLE p); //!< Tells whether an VertexBuffer object is valid
|
|
bool isValid(const Fence* UTILS_NULLABLE p); //!< Tells whether a Fence object is valid
|
|
bool isValid(const IndexBuffer* UTILS_NULLABLE p); //!< Tells whether an IndexBuffer object is valid
|
|
bool isValid(const SkinningBuffer* UTILS_NULLABLE p); //!< Tells whether a SkinningBuffer object is valid
|
|
bool isValid(const MorphTargetBuffer* UTILS_NULLABLE p); //!< Tells whether a MorphTargetBuffer object is valid
|
|
bool isValid(const IndirectLight* UTILS_NULLABLE p); //!< Tells whether an IndirectLight object is valid
|
|
bool isValid(const Material* UTILS_NULLABLE p); //!< Tells whether an IndirectLight object is valid
|
|
bool isValid(const Renderer* UTILS_NULLABLE p); //!< Tells whether a Renderer object is valid
|
|
bool isValid(const Scene* UTILS_NULLABLE p); //!< Tells whether a Scene object is valid
|
|
bool isValid(const Skybox* UTILS_NULLABLE p); //!< Tells whether a SkyBox object is valid
|
|
bool isValid(const ColorGrading* UTILS_NULLABLE p); //!< Tells whether a ColorGrading object is valid
|
|
bool isValid(const SwapChain* UTILS_NULLABLE p); //!< Tells whether a SwapChain object is valid
|
|
bool isValid(const Stream* UTILS_NULLABLE p); //!< Tells whether a Stream object is valid
|
|
bool isValid(const Texture* UTILS_NULLABLE p); //!< Tells whether a Texture object is valid
|
|
bool isValid(const RenderTarget* UTILS_NULLABLE p); //!< Tells whether a RenderTarget object is valid
|
|
bool isValid(const View* UTILS_NULLABLE p); //!< Tells whether a View object is valid
|
|
bool isValid(const InstanceBuffer* UTILS_NULLABLE p); //!< Tells whether an InstanceBuffer object is valid
|
|
|
|
/**
|
|
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) and blocks until
|
|
* all commands to this point are executed. Note that does guarantee that the
|
|
* hardware is actually finished.
|
|
*
|
|
* <p>This is typically used right after destroying the <code>SwapChain</code>,
|
|
* in cases where a guarantee about the <code>SwapChain</code> destruction is needed in a
|
|
* timely fashion, such as when responding to Android's
|
|
* <code>android.view.SurfaceHolder.Callback.surfaceDestroyed</code></p>
|
|
*/
|
|
void flushAndWait();
|
|
|
|
/**
|
|
* Kicks the hardware thread (e.g. the OpenGL, Vulkan or Metal thread) but does not wait
|
|
* for commands to be either executed or the hardware finished.
|
|
*
|
|
* <p>This is typically used after creating a lot of objects to start draining the command
|
|
* queue which has a limited size.</p>
|
|
*/
|
|
void flush();
|
|
|
|
/**
|
|
* Pause or resume rendering thread.
|
|
*
|
|
* <p>Warning: This is an experimental API. In particular, note the following caveats.
|
|
*
|
|
* <ul><li>
|
|
* Buffer callbacks will never be called as long as the rendering thread is paused.
|
|
* Do not rely on a buffer callback to unpause the thread.
|
|
* </li><li>
|
|
* While the rendering thread is paused, rendering commands will continue to be queued until the
|
|
* buffer limit is reached. When the limit is reached, the program will abort.
|
|
* </li></ul>
|
|
*/
|
|
void setPaused(bool paused);
|
|
|
|
/**
|
|
* Drains the user callback message queue and immediately execute all pending callbacks.
|
|
*
|
|
* <p> Typically this should be called once per frame right after the application's vsync tick,
|
|
* and typically just before computing parameters (e.g. object positions) for the next frame.
|
|
* This is useful because otherwise callbacks will be executed by filament at a later time,
|
|
* which may increase latency in certain applications.</p>
|
|
*/
|
|
void pumpMessageQueues();
|
|
|
|
/**
|
|
* Returns the default Material.
|
|
*
|
|
* The default material is 80% white and uses the Material.Shading.LIT shading.
|
|
*
|
|
* @return A pointer to the default Material instance (a singleton).
|
|
*/
|
|
Material const* UTILS_NONNULL getDefaultMaterial() const noexcept;
|
|
|
|
/**
|
|
* Returns the resolved backend.
|
|
*/
|
|
Backend getBackend() const noexcept;
|
|
|
|
/**
|
|
* Returns the Platform object that belongs to this Engine.
|
|
*
|
|
* When Engine::create is called with no platform argument, Filament creates an appropriate
|
|
* Platform subclass automatically. The specific subclass created depends on the backend and
|
|
* OS. For example, when the OpenGL backend is used, the Platform object will be a descendant of
|
|
* OpenGLPlatform.
|
|
*
|
|
* dynamic_cast should be used to cast the returned Platform object into a specific subclass.
|
|
* Note that RTTI must be available to use dynamic_cast.
|
|
*
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
* Platform* platform = engine->getPlatform();
|
|
* // static_cast also works, but more dangerous.
|
|
* SpecificPlatform* specificPlatform = dynamic_cast<SpecificPlatform*>(platform);
|
|
* specificPlatform->platformSpecificMethod();
|
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
*
|
|
* When a custom Platform is passed to Engine::create, Filament will use it instead, and this
|
|
* method will return it.
|
|
*
|
|
* @return A pointer to the Platform object that was provided to Engine::create, or the
|
|
* Filament-created one.
|
|
*/
|
|
Platform* UTILS_NULLABLE getPlatform() const noexcept;
|
|
|
|
/**
|
|
* Allocate a small amount of memory directly in the command stream. The allocated memory is
|
|
* guaranteed to be preserved until the current command buffer is executed
|
|
*
|
|
* @param size size to allocate in bytes. This should be small (e.g. < 1 KB)
|
|
* @param alignment alignment requested
|
|
* @return a pointer to the allocated buffer or nullptr if no memory was available.
|
|
*
|
|
* @note there is no need to destroy this buffer, it will be freed automatically when
|
|
* the current command buffer is executed.
|
|
*/
|
|
void* UTILS_NULLABLE streamAlloc(size_t size, size_t alignment = alignof(double)) noexcept;
|
|
|
|
/**
|
|
* Invokes one iteration of the render loop, used only on single-threaded platforms.
|
|
*
|
|
* This should be called every time the windowing system needs to paint (e.g. at 60 Hz).
|
|
*/
|
|
void execute();
|
|
|
|
/**
|
|
* Retrieves the job system that the Engine has ownership over.
|
|
*
|
|
* @return JobSystem used by filament
|
|
*/
|
|
utils::JobSystem& getJobSystem() noexcept;
|
|
|
|
#if defined(__EMSCRIPTEN__)
|
|
/**
|
|
* WebGL only: Tells the driver to reset any internal state tracking if necessary.
|
|
*
|
|
* This is only useful when integrating an external renderer into Filament on platforms
|
|
* like WebGL, where share contexts do not exist. Filament keeps track of the GL
|
|
* state it has set (like which texture is bound), and does not re-set that state if
|
|
* it does not think it needs to. However, if an external renderer has set different
|
|
* state in the mean time, Filament will use that new state unknowingly.
|
|
*
|
|
* If you are in this situation, call this function - ideally only once per frame,
|
|
* immediately after calling Engine::execute().
|
|
*/
|
|
void resetBackendState() noexcept;
|
|
#endif
|
|
|
|
DebugRegistry& getDebugRegistry() noexcept;
|
|
|
|
protected:
|
|
//! \privatesection
|
|
Engine() noexcept = default;
|
|
~Engine() = default;
|
|
|
|
public:
|
|
//! \privatesection
|
|
Engine(Engine const&) = delete;
|
|
Engine(Engine&&) = delete;
|
|
Engine& operator=(Engine const&) = delete;
|
|
Engine& operator=(Engine&&) = delete;
|
|
};
|
|
|
|
} // namespace filament
|
|
|
|
#endif // TNT_FILAMENT_ENGINE_H
|