Compare commits
37 Commits
ebridgewat
...
v1.9.9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc9e05e711 | ||
|
|
419d68d4db | ||
|
|
8450232448 | ||
|
|
cc51726590 | ||
|
|
318e22af51 | ||
|
|
68ac87dc24 | ||
|
|
acb8f00075 | ||
|
|
06d9183aaa | ||
|
|
75af25419d | ||
|
|
f6b90d2a31 | ||
|
|
a3822f4af0 | ||
|
|
bcdad769ff | ||
|
|
be4fb4fdbb | ||
|
|
65394f6301 | ||
|
|
b0beee03bc | ||
|
|
fe1de41b8e | ||
|
|
a37b431e87 | ||
|
|
98107016b9 | ||
|
|
8bccfc2863 | ||
|
|
f54a0a3452 | ||
|
|
6778ab0624 | ||
|
|
269d636785 | ||
|
|
39862c91ce | ||
|
|
523f4026b4 | ||
|
|
a6bf162431 | ||
|
|
826e8d181c | ||
|
|
16dfadbba0 | ||
|
|
5cbb97551f | ||
|
|
defee767c3 | ||
|
|
9560318521 | ||
|
|
ef09feb048 | ||
|
|
39f323fe09 | ||
|
|
11b95304ea | ||
|
|
b7c30a7916 | ||
|
|
4cae48fc77 | ||
|
|
d1a93f0557 | ||
|
|
b93059fad7 |
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.9.8'
|
||||
implementation 'com.google.android.filament:filament-android:1.9.9'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -63,7 +63,7 @@ A much smaller alternative to `filamat-android` that can only generate OpenGL sh
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.9.8'
|
||||
pod 'Filament', '~> 1.9.9'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
@@ -7,6 +7,13 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## v1.9.9
|
||||
|
||||
- Vulkan: internal robustness improvements
|
||||
- Metal: Support CVPixelBuffer SwapChains
|
||||
- Metal: Support copyFrame
|
||||
- Fix clear behavior with RenderTarget API.
|
||||
- Fix GetRefractionMode JNI binding
|
||||
- Additional fixes for Fence bug
|
||||
|
||||
## v1.9.8
|
||||
|
||||
- Fix a few Fence-related bugs
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.9.8
|
||||
VERSION_NAME=1.9.9
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ public:
|
||||
|
||||
struct Sampler {
|
||||
utils::CString name = {}; // name of the sampler in the shader
|
||||
size_t binding = 0; // binding point of the sampler in the shader
|
||||
uint16_t binding = 0; // binding point of the sampler in the shader
|
||||
bool strict = false; // if true, this sampler must always have a bound texture
|
||||
};
|
||||
|
||||
using SamplerGroupInfo = std::array<std::vector<Sampler>, SAMPLER_BINDING_COUNT>;
|
||||
|
||||
@@ -215,6 +215,7 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* gl) noexcept {
|
||||
Handle<HwTexture> th = samplers[index].t;
|
||||
if (UTILS_UNLIKELY(!th)) {
|
||||
#ifndef NDEBUG
|
||||
slog.w << "In material " << name.c_str() << ": ";
|
||||
slog.w << "no texture bound to unit " << +index << io::endl;
|
||||
#endif
|
||||
continue;
|
||||
|
||||
@@ -957,5 +957,14 @@ void blitColor(VulkanContext* context, const VulkanRenderTarget* dstTarget,
|
||||
}
|
||||
}
|
||||
|
||||
void createEmptyTexture(VulkanContext& context, VulkanStagePool& stagePool) {
|
||||
context.emptyTexture = new VulkanTexture(context, SamplerType::SAMPLER_2D, 1,
|
||||
TextureFormat::RGBA8, 1, 1, 1, 1,
|
||||
TextureUsage::DEFAULT | TextureUsage::COLOR_ATTACHMENT, stagePool);
|
||||
uint32_t black = 0;
|
||||
PixelBufferDescriptor pbd(&black, 4, PixelDataFormat::RGBA, PixelDataType::UBYTE);
|
||||
context.emptyTexture->update2DImage(pbd, 1, 1, 0);
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
} // namespace backend
|
||||
|
||||
@@ -50,6 +50,7 @@ constexpr static const int VK_REQUIRED_VERSION_MINOR = 0;
|
||||
struct VulkanRenderTarget;
|
||||
struct VulkanSurfaceContext;
|
||||
struct VulkanTexture;
|
||||
class VulkanStagePool;
|
||||
|
||||
// This wrapper exists so that we can use shared_ptr to implement shared ownership for low-level
|
||||
// Vulkan fences.
|
||||
@@ -111,6 +112,7 @@ struct VulkanContext {
|
||||
VkViewport viewport;
|
||||
VkFormat finalDepthFormat;
|
||||
VmaAllocator allocator;
|
||||
VulkanTexture* emptyTexture = nullptr;
|
||||
|
||||
// The work context is used for activities unrelated to the swap chain or draw calls, such as
|
||||
// uploads, blits, and transitions.
|
||||
@@ -176,6 +178,7 @@ VkCommandBuffer acquireWorkCommandBuffer(VulkanContext& context);
|
||||
void flushWorkCommandBuffer(VulkanContext& context);
|
||||
void createFinalDepthBuffer(VulkanContext& context, VulkanSurfaceContext& sc, VkFormat depthFormat);
|
||||
VkImageLayout getTextureLayout(TextureUsage usage);
|
||||
void createEmptyTexture(VulkanContext& context, VulkanStagePool& stagePool);
|
||||
|
||||
void blitDepth(VulkanContext* context, const VulkanRenderTarget* dstTarget,
|
||||
const VkOffset3D dstRect[2], const VulkanRenderTarget* srcTarget,
|
||||
|
||||
@@ -195,6 +195,7 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform,
|
||||
// Initialize device and graphicsQueue.
|
||||
createLogicalDevice(mContext);
|
||||
mBinder.setDevice(mContext.device);
|
||||
createEmptyTexture(mContext, mStagePool);
|
||||
|
||||
// Choose a depth format that meets our requirements. Take care not to include stencil formats
|
||||
// just yet, since that would require a corollary change to the "aspect" flags for the VkImage.
|
||||
@@ -247,6 +248,9 @@ void VulkanDriver::terminate() {
|
||||
|
||||
// Flush the work command buffer.
|
||||
acquireWorkCommandBuffer(mContext);
|
||||
|
||||
delete mContext.emptyTexture;
|
||||
|
||||
mDisposer.release(mContext.work.resources);
|
||||
|
||||
// Allow the stage pool and disposer to clean up.
|
||||
@@ -1592,14 +1596,28 @@ void VulkanDriver::draw(PipelineState pipelineState, Handle<HwRenderPrimitive> r
|
||||
const SamplerGroup::Sampler* boundSampler = sb->getSamplers() + samplerIdx;
|
||||
samplerIdx++;
|
||||
|
||||
if (!boundSampler->t) {
|
||||
continue;
|
||||
// Note that we always use a 2D texture for the fallback texture, which might not be
|
||||
// appropriate. The fallback improves robustness but does not guarantee 100% success.
|
||||
// It can be argued that clients are being malfeasant here anyway, since Vulkan does
|
||||
// not allow sampling from a non-bound texture.
|
||||
const VulkanTexture* texture;
|
||||
if (UTILS_UNLIKELY(!boundSampler->t)) {
|
||||
if (!sampler.strict) {
|
||||
continue;
|
||||
}
|
||||
utils::slog.w << "No texture bound to '" << sampler.name.c_str() << "'";
|
||||
#ifndef NDEBUG
|
||||
utils::slog.w << " in material '" << program->name.c_str() << "'";
|
||||
#endif
|
||||
utils::slog.w << " at binding point " << +bindingPoint << utils::io::endl;
|
||||
texture = mContext.emptyTexture;
|
||||
} else {
|
||||
texture = handle_const_cast<VulkanTexture>(mHandleMap, boundSampler->t);
|
||||
mDisposer.acquire(texture, commands->resources);
|
||||
}
|
||||
|
||||
const SamplerParams& samplerParams = boundSampler->s;
|
||||
VkSampler vksampler = mSamplerCache.getSampler(samplerParams);
|
||||
const auto* texture = handle_const_cast<VulkanTexture>(mHandleMap, boundSampler->t);
|
||||
mDisposer.acquire(texture, commands->resources);
|
||||
|
||||
mBinder.bindSampler(bindingPoint, {
|
||||
.sampler = vksampler,
|
||||
|
||||
@@ -44,6 +44,34 @@ namespace filament {
|
||||
|
||||
using namespace backend;
|
||||
|
||||
static MaterialParser* createParser(Backend backend, const void* data, size_t size) {
|
||||
MaterialParser* materialParser = new MaterialParser(backend, data, size);
|
||||
|
||||
MaterialParser::ParseResult materialResult = materialParser->parse();
|
||||
|
||||
if (backend == Backend::NOOP) {
|
||||
return materialParser;
|
||||
}
|
||||
|
||||
if (!ASSERT_POSTCONDITION_NON_FATAL(materialResult != MaterialParser::ParseResult::ERROR_MISSING_BACKEND,
|
||||
"the material was not built for the %s backend\n", backendToString(backend))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ASSERT_POSTCONDITION_NON_FATAL(materialResult == MaterialParser::ParseResult::SUCCESS,
|
||||
"could not parse the material package")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t version = 0;
|
||||
materialParser->getMaterialVersion(&version);
|
||||
ASSERT_PRECONDITION(version == MATERIAL_VERSION, "Material version mismatch. Expected %d but "
|
||||
"received %d.", MATERIAL_VERSION, version);
|
||||
|
||||
assert(backend != Backend::DEFAULT && "Default backend has not been resolved.");
|
||||
|
||||
return materialParser;
|
||||
}
|
||||
|
||||
struct Material::BuilderDetails {
|
||||
const void* mPayload = nullptr;
|
||||
@@ -71,7 +99,7 @@ Material::Builder& Material::Builder::package(const void* payload, size_t size)
|
||||
}
|
||||
|
||||
Material* Material::Builder::build(Engine& engine) {
|
||||
MaterialParser* materialParser = FMaterial::createParser(
|
||||
MaterialParser* materialParser = createParser(
|
||||
upcast(engine).getBackend(), mImpl->mPayload, mImpl->mSize);
|
||||
|
||||
uint32_t v = 0;
|
||||
@@ -79,15 +107,15 @@ Material* Material::Builder::build(Engine& engine) {
|
||||
utils::bitset32 shaderModels;
|
||||
shaderModels.setValue(v);
|
||||
|
||||
backend::ShaderModel shaderModel = upcast(engine).getDriver().getShaderModel();
|
||||
ShaderModel shaderModel = upcast(engine).getDriver().getShaderModel();
|
||||
if (!shaderModels.test(static_cast<uint32_t>(shaderModel))) {
|
||||
CString name;
|
||||
materialParser->getName(&name);
|
||||
slog.e << "The material '" << name.c_str_safe() << "' was not built for ";
|
||||
switch (shaderModel) {
|
||||
case backend::ShaderModel::GL_ES_30: slog.e << "mobile.\n"; break;
|
||||
case backend::ShaderModel::GL_CORE_41: slog.e << "desktop.\n"; break;
|
||||
case backend::ShaderModel::UNKNOWN: /* should never happen */ break;
|
||||
case ShaderModel::GL_ES_30: slog.e << "mobile.\n"; break;
|
||||
case ShaderModel::GL_CORE_41: slog.e << "desktop.\n"; break;
|
||||
case ShaderModel::UNKNOWN: /* should never happen */ break;
|
||||
}
|
||||
slog.e << "Compiled material contains shader models 0x"
|
||||
<< io::hex << shaderModels.getValue() << io::dec << "." << io::endl;
|
||||
@@ -123,7 +151,8 @@ static void addSamplerGroup(Program& pb, uint8_t bindingPoint, SamplerInterfaceB
|
||||
uint8_t binding = 0;
|
||||
UTILS_UNUSED bool ok = map.getSamplerBinding(bindingPoint, (uint8_t)i, &binding);
|
||||
assert(ok);
|
||||
samplers[i] = { std::move(uniformName), binding };
|
||||
const bool strict = (bindingPoint == filament::BindingPoints::PER_MATERIAL_INSTANCE);
|
||||
samplers[i] = { std::move(uniformName), binding, strict };
|
||||
}
|
||||
pb.setSamplerGroup(bindingPoint, samplers.data(), samplers.size());
|
||||
}
|
||||
@@ -311,7 +340,7 @@ UniformInterfaceBlock::UniformInfo const* FMaterial::reflect(
|
||||
return p == list.end() ? nullptr : &static_cast<UniformInterfaceBlock::UniformInfo const&>(*p);
|
||||
}
|
||||
|
||||
backend::Handle<backend::HwProgram> FMaterial::getProgramSlow(uint8_t variantKey) const noexcept {
|
||||
Handle<HwProgram> FMaterial::getProgramSlow(uint8_t variantKey) const noexcept {
|
||||
switch (getMaterialDomain()) {
|
||||
case MaterialDomain::SURFACE:
|
||||
return getSurfaceProgramSlow(variantKey);
|
||||
@@ -321,7 +350,7 @@ backend::Handle<backend::HwProgram> FMaterial::getProgramSlow(uint8_t variantKey
|
||||
}
|
||||
}
|
||||
|
||||
backend::Handle<backend::HwProgram> FMaterial::getSurfaceProgramSlow(uint8_t variantKey)
|
||||
Handle<HwProgram> FMaterial::getSurfaceProgramSlow(uint8_t variantKey)
|
||||
const noexcept {
|
||||
// filterVariant() has already been applied in generateCommands(), shouldn't be needed here
|
||||
// if we're unlit, we don't have any bits that correspond to lit materials
|
||||
@@ -351,7 +380,7 @@ backend::Handle<backend::HwProgram> FMaterial::getSurfaceProgramSlow(uint8_t var
|
||||
return createAndCacheProgram(std::move(pb), variantKey);
|
||||
}
|
||||
|
||||
backend::Handle<backend::HwProgram> FMaterial::getPostProcessProgramSlow(uint8_t variantKey)
|
||||
Handle<HwProgram> FMaterial::getPostProcessProgramSlow(uint8_t variantKey)
|
||||
const noexcept {
|
||||
|
||||
Program pb = getProgramBuilderWithVariants(variantKey, variantKey, variantKey);
|
||||
@@ -369,6 +398,7 @@ Program FMaterial::getProgramBuilderWithVariants(
|
||||
uint8_t vertexVariantKey,
|
||||
uint8_t fragmentVariantKey) const noexcept {
|
||||
const ShaderModel sm = mEngine.getDriver().getShaderModel();
|
||||
const bool isNoop = mEngine.getBackend() == Backend::NOOP;
|
||||
|
||||
/*
|
||||
* Vertex shader
|
||||
@@ -379,7 +409,7 @@ Program FMaterial::getProgramBuilderWithVariants(
|
||||
UTILS_UNUSED_IN_RELEASE bool vsOK = mMaterialParser->getShader(vsBuilder, sm,
|
||||
vertexVariantKey, ShaderType::VERTEX);
|
||||
|
||||
ASSERT_POSTCONDITION(vsOK && vsBuilder.size() > 0,
|
||||
ASSERT_POSTCONDITION(isNoop || (vsOK && vsBuilder.size() > 0),
|
||||
"The material '%s' has not been compiled to include the required "
|
||||
"GLSL or SPIR-V chunks for the vertex shader (variant=0x%x, filtered=0x%x).",
|
||||
mName.c_str(), variantKey, vertexVariantKey);
|
||||
@@ -393,7 +423,7 @@ Program FMaterial::getProgramBuilderWithVariants(
|
||||
UTILS_UNUSED_IN_RELEASE bool fsOK = mMaterialParser->getShader(fsBuilder, sm,
|
||||
fragmentVariantKey, ShaderType::FRAGMENT);
|
||||
|
||||
ASSERT_POSTCONDITION(fsOK && fsBuilder.size() > 0,
|
||||
ASSERT_POSTCONDITION(isNoop || (fsOK && fsBuilder.size() > 0),
|
||||
"The material '%s' has not been compiled to include the required "
|
||||
"GLSL or SPIR-V chunks for the fragment shader (variant=0x%x, filterer=0x%x).",
|
||||
mName.c_str(), variantKey, fragmentVariantKey);
|
||||
@@ -405,7 +435,7 @@ Program FMaterial::getProgramBuilderWithVariants(
|
||||
return pb;
|
||||
}
|
||||
|
||||
backend::Handle<backend::HwProgram> FMaterial::createAndCacheProgram(Program&& p,
|
||||
Handle<HwProgram> FMaterial::createAndCacheProgram(Program&& p,
|
||||
uint8_t variantKey) const noexcept {
|
||||
auto program = mEngine.getDriverApi().createProgram(std::move(p));
|
||||
assert(program);
|
||||
@@ -463,7 +493,7 @@ void FMaterial::applyPendingEdits() noexcept {
|
||||
/**
|
||||
* Callback handlers for the debug server, potentially called from any thread. These methods are
|
||||
* never called during normal operation and exist for debugging purposes only.
|
||||
*
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
@@ -474,8 +504,7 @@ void FMaterial::onEditCallback(void* userdata, const utils::CString& name, const
|
||||
|
||||
// This is called on a web server thread so we defer clearing the program cache
|
||||
// and swapping out the MaterialParser until the next getProgram call.
|
||||
material->mPendingEdits = FMaterial::createParser(engine.getBackend(), packageData,
|
||||
packageSize);
|
||||
material->mPendingEdits = createParser(engine.getBackend(), packageData, packageSize);
|
||||
}
|
||||
|
||||
void FMaterial::onQueryCallback(void* userdata, uint64_t* pVariants) {
|
||||
@@ -492,31 +521,6 @@ void FMaterial::onQueryCallback(void* userdata, uint64_t* pVariants) {
|
||||
|
||||
/** @}*/
|
||||
|
||||
MaterialParser* FMaterial::createParser(backend::Backend backend, const void* data, size_t size) {
|
||||
MaterialParser* materialParser = new MaterialParser(backend, data, size);
|
||||
|
||||
MaterialParser::ParseResult materialResult = materialParser->parse();
|
||||
|
||||
if (!ASSERT_POSTCONDITION_NON_FATAL(materialResult != MaterialParser::ParseResult::ERROR_MISSING_BACKEND,
|
||||
"the material was not built for the %s backend\n", backendToString(backend))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ASSERT_POSTCONDITION_NON_FATAL(materialResult == MaterialParser::ParseResult::SUCCESS,
|
||||
"could not parse the material package")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t version = 0;
|
||||
materialParser->getMaterialVersion(&version);
|
||||
ASSERT_PRECONDITION(version == MATERIAL_VERSION, "Material version mismatch. Expected %d but "
|
||||
"received %d.", MATERIAL_VERSION, version);
|
||||
|
||||
assert(backend != Backend::DEFAULT && "Default backend has not been resolved.");
|
||||
|
||||
return materialParser;
|
||||
}
|
||||
|
||||
void FMaterial::destroyPrograms(FEngine& engine) {
|
||||
DriverApi& driverApi = engine.getDriverApi();
|
||||
auto& cachedPrograms = mCachedPrograms;
|
||||
|
||||
@@ -228,6 +228,12 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) {
|
||||
return;
|
||||
}
|
||||
|
||||
FRenderTarget* currentRenderTarget = upcast(view.getRenderTarget());
|
||||
if (mPreviousRenderTarget != currentRenderTarget) {
|
||||
initializeClearFlags();
|
||||
mPreviousRenderTarget = currentRenderTarget;
|
||||
}
|
||||
|
||||
view.prepare(engine, driver, arena, svp, getShaderUserTime());
|
||||
|
||||
// start froxelization immediately, it has no dependencies
|
||||
@@ -899,14 +905,8 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
|
||||
float l = float(time.count() - h);
|
||||
mShaderUserTime = { h, l, 0, 0 };
|
||||
|
||||
// We always discard and clear the depth+stencil buffers -- we don't allow sharing these
|
||||
// across views (clear implies discard)
|
||||
mDiscardedFlags = ((mClearOptions.discard || mClearOptions.clear) ?
|
||||
TargetBufferFlags::COLOR : TargetBufferFlags::NONE)
|
||||
| TargetBufferFlags::DEPTH_AND_STENCIL;
|
||||
|
||||
mClearFlags = (mClearOptions.clear ? TargetBufferFlags::COLOR : TargetBufferFlags::NONE)
|
||||
| TargetBufferFlags::DEPTH_AND_STENCIL;
|
||||
initializeClearFlags();
|
||||
mPreviousRenderTarget = nullptr;
|
||||
|
||||
mBeginFrameInternal = {};
|
||||
|
||||
@@ -1099,6 +1099,17 @@ Handle<HwRenderTarget> FRenderer::getRenderTarget(FView& view) const noexcept {
|
||||
return viewRenderTarget ? viewRenderTarget : mRenderTarget;
|
||||
}
|
||||
|
||||
void FRenderer::initializeClearFlags() {
|
||||
// We always discard and clear the depth+stencil buffers -- we don't allow sharing these
|
||||
// across views (clear implies discard)
|
||||
mDiscardedFlags = ((mClearOptions.discard || mClearOptions.clear) ?
|
||||
TargetBufferFlags::COLOR : TargetBufferFlags::NONE)
|
||||
| TargetBufferFlags::DEPTH_AND_STENCIL;
|
||||
|
||||
mClearFlags = (mClearOptions.clear ? TargetBufferFlags::COLOR : TargetBufferFlags::NONE)
|
||||
| TargetBufferFlags::DEPTH_AND_STENCIL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Trampoline calling into private implementation
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -153,8 +153,6 @@ public:
|
||||
|
||||
/** @}*/
|
||||
|
||||
static MaterialParser* createParser(backend::Backend backend, const void* data, size_t size);
|
||||
|
||||
private:
|
||||
backend::Handle<backend::HwProgram> getProgramSlow(uint8_t variantKey) const noexcept;
|
||||
backend::Handle<backend::HwProgram> getSurfaceProgramSlow(uint8_t variantKey) const noexcept;
|
||||
|
||||
@@ -49,6 +49,7 @@ class Driver;
|
||||
class View;
|
||||
|
||||
class FEngine;
|
||||
class FRenderTarget;
|
||||
class FView;
|
||||
class ShadowMap;
|
||||
|
||||
@@ -161,6 +162,8 @@ private:
|
||||
backend::TextureFormat getHdrFormat(const View& view, bool translucent) const noexcept;
|
||||
backend::TextureFormat getLdrFormat(bool translucent) const noexcept;
|
||||
|
||||
void initializeClearFlags();
|
||||
|
||||
using clock = std::chrono::steady_clock;
|
||||
using Epoch = clock::time_point;
|
||||
using duration = clock::duration;
|
||||
@@ -189,6 +192,7 @@ private:
|
||||
ClearOptions mClearOptions;
|
||||
backend::TargetBufferFlags mDiscardedFlags{};
|
||||
backend::TargetBufferFlags mClearFlags{};
|
||||
FRenderTarget* mPreviousRenderTarget = nullptr;
|
||||
std::function<void()> mBeginFrameInternal;
|
||||
|
||||
// per-frame arena for this Renderer
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "Filament"
|
||||
spec.version = "1.9.8"
|
||||
spec.version = "1.9.9"
|
||||
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
|
||||
spec.homepage = "https://google.github.io/filament"
|
||||
spec.authors = "Google LLC."
|
||||
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
|
||||
spec.platform = :ios, "11.0"
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.8/filament-v1.9.8-ios.tgz" }
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.9.9/filament-v1.9.9-ios.tgz" }
|
||||
|
||||
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
|
||||
spec.pod_target_xcconfig = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "filament",
|
||||
"version": "1.9.8",
|
||||
"version": "1.9.9",
|
||||
"description": "Real-time physically based rendering engine",
|
||||
"main": "filament.js",
|
||||
"module": "filament.js",
|
||||
|
||||
Reference in New Issue
Block a user