Skip to content

Commit 9da29e3

Browse files
authored
Add new public API to query a sampler transform name field. (#9320)
* Add new public API to query a sampler transform name field. This new API will let filament users query a Material object the value of the `transformName` field of a specified sampler parameter. The transformName is an optional field, so if its not defined by the user, it will return a nullptr value. - A new test was added to test_filamat to validate the serialization. - A new parameter was added to the test sandboxLit material to validate the parsing a material with the new field. * Addressing review comments - Add java and js bindings for the new API - Tests for querying the getParameterTransformName * Use utils::ImmutableCString for transformName * Updating release notes * Review comments * Addressing more review comments - Fix comments - For the java binding return an empty string when the transform is not present.
1 parent e60280e commit 9da29e3

File tree

20 files changed

+283
-19
lines changed

20 files changed

+283
-19
lines changed

NEW_RELEASE_NOTES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@
66
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
77

88
## Release notes for next branch cut
9+
10+
- materials: Add a new API getParameterTransformName that will return the value of the transformName field of a sampler
11+
parameter. [⚠️ **Recompile Materials**]

android/filament-android/src/main/cpp/Material.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,17 @@ Java_com_google_android_filament_Material_nHasParameter(JNIEnv* env, jclass,
279279
return (jboolean) hasParameter;
280280
}
281281

282+
extern "C" JNIEXPORT jstring JNICALL
283+
Java_com_google_android_filament_Material_nGetParameterTransformName(JNIEnv* env, jclass,
284+
jlong nativeMaterial, jstring samplerName_) {
285+
Material* material = (Material*) nativeMaterial;
286+
const char* samplerName = env->GetStringUTFChars(samplerName_, 0);
287+
const char* transformName = material->getParameterTransformName(samplerName);
288+
jstring transformName_ = env->NewStringUTF(transformName ? transformName : "");
289+
env->ReleaseStringUTFChars(samplerName_, samplerName);
290+
return transformName_;
291+
}
292+
282293
extern "C"
283294
JNIEXPORT void JNICALL
284295
Java_com_google_android_filament_Material_nCompile(JNIEnv *env, jclass clazz,

android/filament-android/src/main/java/com/google/android/filament/Material.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,21 @@ public boolean hasParameter(@NonNull String name) {
787787
return nHasParameter(getNativeObject(), name);
788788
}
789789

790+
/**
791+
*
792+
* Returns the name of the transform parameter associated with the given sampler parameter.
793+
* In the case the parameter doesn't have a transform name field, it will return an empty string.
794+
*
795+
* @param samplerName the name of the sampler parameter to query.
796+
*
797+
* @see
798+
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/general:parameters">
799+
* General: parameters</a>
800+
*/
801+
public String getParameterTransformName(@NonNull String samplerName) {
802+
return nGetParameterTransformName(getNativeObject(), samplerName);
803+
}
804+
790805
/**
791806
* Sets the value of a bool parameter on this material's default instance.
792807
*
@@ -1111,4 +1126,5 @@ private static native void nGetParameters(long nativeMaterial,
11111126
private static native int nGetRequiredAttributes(long nativeMaterial);
11121127

11131128
private static native boolean nHasParameter(long nativeMaterial, @NonNull String name);
1129+
private static native String nGetParameterTransformName(long nativeMaterial, @NonNull String samplerName);
11141130
}

filament/include/filament/Material.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,19 @@ class UTILS_PUBLIC Material : public FilamentAPI {
350350
//! Indicates whether an existing parameter is a sampler or not.
351351
bool isSampler(const char* UTILS_NONNULL name) const noexcept;
352352

353+
354+
/**
355+
*
356+
* Gets the name of the transform field associated for the given sampler parameter.
357+
* In the case where the parameter does not have a transform name field, it will return nullptr.
358+
*
359+
* @param samplerName the name of the sampler parameter to query.
360+
*
361+
* @return If exists, the transform name value otherwise returns a nullptr.
362+
*/
363+
const char* UTILS_NULLABLE getParameterTransformName(
364+
const char* UTILS_NONNULL samplerName) const noexcept;
365+
353366
/**
354367
* Sets the value of the given parameter on this material's default instance.
355368
*

filament/src/Material.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ bool Material::isSampler(const char* name) const noexcept {
146146
return downcast(this)->isSampler(name);
147147
}
148148

149+
const char* Material::getParameterTransformName(const char* samplerName) const noexcept {
150+
return downcast(this)->getParameterTransformName(samplerName);
151+
}
152+
149153
MaterialInstance* Material::getDefaultInstance() noexcept {
150154
return downcast(this)->getDefaultInstance();
151155
}

filament/src/MaterialParser.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
542542
uint8_t fieldPrecision = 0;
543543
bool fieldFilterable = false;
544544
bool fieldMultisample = false;
545+
CString fieldTransformName;
545546

546547
if (!unflattener.read(&fieldName)) {
547548
return false;
@@ -571,13 +572,18 @@ bool ChunkSamplerInterfaceBlock::unflatten(Unflattener& unflattener,
571572
return false;
572573
}
573574

575+
if (!unflattener.read(&fieldTransformName)) {
576+
return false;
577+
}
578+
574579
builder.add({ fieldName.data(), fieldName.size() },
575580
SamplerInterfaceBlock::Binding(fieldBinding),
576581
SamplerInterfaceBlock::Type(fieldType),
577582
SamplerInterfaceBlock::Format(fieldFormat),
578583
SamplerInterfaceBlock::Precision(fieldPrecision),
579584
fieldFilterable,
580-
fieldMultisample);
585+
fieldMultisample,
586+
{ fieldTransformName.data(), fieldTransformName.size() });
581587
}
582588

583589
*sib = builder.build();

filament/src/details/Material.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,15 @@ descriptor_binding_t FMaterial::getSamplerBinding(
822822
return mDefinition.samplerInterfaceBlock.getSamplerInfo(name)->binding;
823823
}
824824

825+
const char* FMaterial::getParameterTransformName(std::string_view samplerName) const noexcept {
826+
auto const& sib = getSamplerInterfaceBlock();
827+
SamplerInterfaceBlock::SamplerInfo const* info = sib.getSamplerInfo(samplerName);
828+
if (!info || info->transformName.empty()) {
829+
return nullptr;
830+
}
831+
return info->transformName.c_str();
832+
}
833+
825834
template bool FMaterial::setConstant<int32_t>(uint32_t id, int32_t value) noexcept;
826835
template bool FMaterial::setConstant<float>(uint32_t id, float value) noexcept;
827836
template bool FMaterial::setConstant<bool>(uint32_t id, bool value) noexcept;

filament/src/details/Material.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ class FMaterial : public Material {
213213
backend::descriptor_binding_t getSamplerBinding(
214214
std::string_view const& name) const;
215215

216+
const char* getParameterTransformName(std::string_view samplerName) const noexcept;
217+
216218
bool hasMaterialProperty(Property property) const noexcept {
217219
return bool(mDefinition.materialProperties & uint64_t(property));
218220
}

filament/test/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ file(MAKE_DIRECTORY ${RESOURCE_DIR})
1616
get_resgen_vars(${RESOURCE_DIR} filament_test_resources)
1717

1818
set(RESOURCE_BINS
19-
${CMAKE_CURRENT_SOURCE_DIR}/test_material.filamat)
19+
${CMAKE_CURRENT_SOURCE_DIR}/test_material.filamat
20+
${CMAKE_CURRENT_SOURCE_DIR}/test_material_transformname.filamat
21+
)
2022

2123
add_custom_command(
2224
OUTPUT ${RESGEN_OUTPUTS}
@@ -75,3 +77,11 @@ target_link_libraries(test_material_parser PRIVATE filament gtest)
7577
target_compile_options(test_material_parser PRIVATE ${COMPILER_FLAGS})
7678
target_include_directories(test_material_parser PRIVATE ${RESOURCE_DIR})
7779
set_target_properties(test_material_parser PROPERTIES FOLDER Tests)
80+
81+
add_executable(test_material
82+
filament_test_material.cpp
83+
${RESGEN_SOURCE})
84+
target_link_libraries(test_material PRIVATE filament gtest)
85+
target_compile_options(test_material PRIVATE ${COMPILER_FLAGS})
86+
target_include_directories(test_material PRIVATE ${RESOURCE_DIR})
87+
set_target_properties(test_material PROPERTIES FOLDER Tests)
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (C) 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <gtest/gtest.h>
18+
19+
#include <filament/Engine.h>
20+
#include <filament/Material.h>
21+
22+
#include "filament_test_resources.h"
23+
24+
using namespace filament;
25+
26+
TEST(MaterialTransformName, QuerySamplerWithTransform) {
27+
Engine* engine = Engine::create(Engine::Backend::DEFAULT);
28+
29+
Material* material = Material::Builder()
30+
.package(FILAMENT_TEST_RESOURCES_TEST_MATERIAL_TRANSFORMNAME_DATA,
31+
FILAMENT_TEST_RESOURCES_TEST_MATERIAL_TRANSFORMNAME_SIZE)
32+
.build(*engine);
33+
ASSERT_NE(material, nullptr);
34+
35+
EXPECT_STREQ(material->getParameterTransformName("sampler"), "transform");
36+
37+
engine->destroy(material);
38+
Engine::destroy(engine);
39+
}
40+
41+
TEST(MaterialTransformName, QueryMultipleSamplersWithTransforms) {
42+
Engine* engine = Engine::create(Engine::Backend::DEFAULT);
43+
44+
Material* material = Material::Builder()
45+
.package(FILAMENT_TEST_RESOURCES_TEST_MATERIAL_TRANSFORMNAME_DATA,
46+
FILAMENT_TEST_RESOURCES_TEST_MATERIAL_TRANSFORMNAME_SIZE)
47+
.build(*engine);
48+
ASSERT_NE(material, nullptr);
49+
50+
EXPECT_STREQ(material->getParameterTransformName("sampler"), "transform");
51+
EXPECT_STREQ(material->getParameterTransformName("videoTexture"), "videoTransform");
52+
53+
engine->destroy(material);
54+
Engine::destroy(engine);
55+
}
56+
57+
TEST(MaterialTransformName, QuerySamplerWithoutTransform) {
58+
Engine* engine = Engine::create(Engine::Backend::DEFAULT);
59+
Material* material = Material::Builder()
60+
.package(FILAMENT_TEST_RESOURCES_TEST_MATERIAL_TRANSFORMNAME_DATA,
61+
FILAMENT_TEST_RESOURCES_TEST_MATERIAL_TRANSFORMNAME_SIZE)
62+
.build(*engine);
63+
ASSERT_NE(material, nullptr);
64+
65+
EXPECT_EQ(material->getParameterTransformName("sampler2"), nullptr);
66+
67+
engine->destroy(material);
68+
Engine::destroy(engine);
69+
}
70+
71+
TEST(MaterialTransformName, QueryMultipleSamplersWithoutTransforms) {
72+
Engine* engine = Engine::create(Engine::Backend::DEFAULT);
73+
74+
Material* material = Material::Builder()
75+
.package(FILAMENT_TEST_RESOURCES_TEST_MATERIAL_TRANSFORMNAME_DATA,
76+
FILAMENT_TEST_RESOURCES_TEST_MATERIAL_TRANSFORMNAME_SIZE)
77+
.build(*engine);
78+
ASSERT_NE(material, nullptr);
79+
80+
EXPECT_EQ(material->getParameterTransformName("sampler1"), nullptr);
81+
EXPECT_EQ(material->getParameterTransformName("sampler3"), nullptr);
82+
83+
engine->destroy(material);
84+
Engine::destroy(engine);
85+
}
86+
87+
int main(int argc, char** argv) {
88+
::testing::InitGoogleTest(&argc, argv);
89+
return RUN_ALL_TESTS();
90+
}

0 commit comments

Comments
 (0)