[WebGPU] Adds Support experimental Kotlin/JNI bindings Enables code generation for 'art_experimental' tagged elements in dawn.json to support experimental apis (AHB, Sync FD, external textures). - Update dawn_json_generator to include the 'art_experimental' tag. - Map the 'int' type to 'jint' in dawn_kotlin.json. - Tag external textures, AHB, and Sync FD APIs as 'art_experimental'. - Add newly generated files to tools/android/BUILD.gn - Support customizing Kotlin structure members (add/exclude) via dawn_kotlin.json. Bug: b/518640970 Change-Id: Ibc603423a1673b1a299c76df5ae55e0a6eedb409 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/311495 Reviewed-by: Nikita Gupta <nikigupta@google.com> Commit-Queue: Mridul Goyal <mridulgoyal@google.com> Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py index 9a51537..723fec4e 100644 --- a/generator/dawn_json_generator.py +++ b/generator/dawn_json_generator.py
@@ -114,6 +114,7 @@ 'native', 'deprecated', 'art', + 'art_experimental', } tags = json_data.get('tags') @@ -946,7 +947,9 @@ kotlin_json, webgpu_kt_docs_data=None, doc_warn_log_file_path=None): - params_kotlin = parse_json(loaded_json, enabled_tags=['art']) + + params_kotlin = parse_json(loaded_json, + enabled_tags=['art', 'art_experimental']) params_kotlin['kotlin_package'] = kotlin_json['kotlin_package'] params_kotlin['jni_primitives'] = kotlin_json['jni_primitives'] params_kotlin['jni_signatures'] = kotlin_json['jni_signatures'] @@ -957,12 +960,13 @@ customize_enums = customize_api["enums"] customize_callback = customize_api["function pointer"] - def kotlin_record_members(members): + def kotlin_record_members(members, structure_name=None): # Members are sorted in the following order. # 1. members with no default value (except callbacks). # 2. members with default values. # 3. callbacks. - for member in sorted(kotlin_record_members_unsorted(members), + for member in sorted(kotlin_record_members_unsorted( + members, structure_name), key=lambda arg: kotlin_default(arg) is not None): yield member @@ -978,7 +982,11 @@ yield function_member continue - def kotlin_record_members_unsorted(members): + def kotlin_record_members_unsorted(members, structure_name=None): + struct_config = customize_structures.get(structure_name, + {}) if structure_name else {} + exclude_members = struct_config.get('exclude_members', []) + for member in members: # length parameters are omitted because Kotlin containers have 'length'. if member in [m.length for m in members]: @@ -1002,8 +1010,29 @@ {'category': 'kotlin type'}), None, {}) continue + if member.name.get() in exclude_members or member.name.camelCase( + ) in exclude_members: + continue + yield member + for added_member in struct_config.get('additional_members', []): + name = Name(added_member['name']) + # Default to native for simple types if not specified + category = added_member.get('category', 'native') + type_name = added_member['type'] + if type_name in params_kotlin['types']: + typ = params_kotlin['types'][type_name] + else: + typ = Type(type_name, {'category': category}) + yield RecordMember(name, + typ, + added_member.get('annotation', 'value'), {}, + optional=added_member.get('optional', False), + default_value=added_member.get( + 'default_value', None), + skip_serialize=True) + # Calculate if we should, and can, provide a Kotlin default value for a given argument. # This will affect its order in the method parameter and structure field lists. def kotlin_default(arg): @@ -1014,8 +1043,10 @@ if arg.type.category in [ 'callback function', 'callback info', 'function pointer', 'object', 'structure' - ]: + ] or arg.type.name.get() == 'char': return 'arrayOf()' + if arg.type.name.get() == 'float': + return 'floatArrayOf()' return 'intArrayOf()' # All other optional types default to 'null'. @@ -1347,6 +1378,19 @@ def item_is_enabled(enabled_tags, json_data): tags = validate_and_get_tags(json_data) if tags is None: return True + + # Strip 'art_experimental' for non-Art targets so it doesn't cause + # the item to be excluded from C++/Emscripten builds. + if not ('art_experimental' in enabled_tags): + original_tags_empty = not tags + tags = [tag for tag in tags if tag not in ('art_experimental')] + # NOTE: If an item is tagged ONLY with 'art_experimental', it is disabled + # for non-Art targets. + if not tags and not original_tags_empty: + return False + if not tags: + return True + return any(tag in enabled_tags for tag in tags)
diff --git a/generator/templates/art/api_jni_types.cpp b/generator/templates/art/api_jni_types.cpp index fb272a1..9b4b27a 100644 --- a/generator/templates/art/api_jni_types.cpp +++ b/generator/templates/art/api_jni_types.cpp
@@ -28,15 +28,19 @@ {% macro arg_to_jni_type(arg) %} {%- if arg == None -%} void - {%- elif arg.length and arg.length != 'constant' -%} + {%- elif arg.length and (arg.length != 'constant' or arg.constant_length != 1) -%} {%- if arg.type.category in ['callback function', 'function pointer', 'kotlin type', 'object', 'structure'] -%} jobjectArray {%- elif arg.type.name.get() == 'void' -%} jobject - {%- elif arg.type.category in ['bitmask', 'enum'] or arg.type.name.get() == 'uint32_t' -%} + {%- elif arg.type.category in ['bitmask', 'enum'] or arg.type.name.get() in ['int', 'int32_t', 'uint32_t'] -%} jintArray + {%- elif arg.type.name.get() == 'float' -%} + jfloatArray + {%- elif arg.type.name.get() == 'char' -%} + jobjectArray {%- else -%} - {{ unreachable_code() }} + {{ unreachable_code('Unsupported array type in arg_to_jni_type: ' ~ arg.type.name.get()) }} {%- endif -%} {%- else -%} {{ to_jni_type(arg.type) }} @@ -58,7 +62,7 @@ {% macro jni_signature(member) %} {%- if member.type.name.get() == 'string view' -%} Ljava/lang/String; - {%- elif member.length and member.length != 'constant' -%} + {%- elif member.length and (member.length != 'constant' or member.constant_length != 1) -%} [{{ jni_signature_single_value(member.type) }} {%- else -%} {{ jni_signature_single_value(member.type) }} @@ -71,14 +75,18 @@ {%- elif type.category in ['bitmask', 'enum'] -%} {{ jni_signatures['int32_t'] }} {%- elif type.category == 'native' -%} - {{ jni_signatures[type.name.get()] }} + {%- if type.name.get() == 'char' -%} + Ljava/lang/String; + {%- else -%} + {{ jni_signatures[type.name.get()] }} + {%- endif -%} {%- else -%} {{ unreachable_code('Unsupported type: ' + type.name.get()) }} {%- endif -%} {% endmacro %} {% macro convert_to_kotlin(input, output, size, member) %} - {% if size is string %} + {% if size %} {% if member.type.name.get() in ['void const *', 'void *'] %} jobject {{ output }} = toByteBuffer(env, {{ input }}, {{ size }}); {% elif member.type.category in ['object', 'structure'] %} @@ -92,8 +100,18 @@ {% elif member.type.category in ['bitmask', 'enum'] or member.type.name.get() in ['int', 'int32_t', 'uint32_t'] %} jintArray {{ output }} = env->NewIntArray({{ size }}); {{' '}}env->SetIntArrayRegion({{ output }}, 0, {{ size }}, reinterpret_cast<const jint *>({{ input }})); + {% elif member.type.name.get() == 'float' %} + jfloatArray {{ output }} = env->NewFloatArray({{ size }}); + {{' '}}env->SetFloatArrayRegion({{ output }}, 0, {{ size }}, reinterpret_cast<const jfloat *>({{ input }})); + {% elif member.type.name.get() == 'char' and member.annotation == 'const*const*' %} + jobjectArray {{ output }} = env->NewObjectArray({{ size }}, classes->stringClass, nullptr); + for (int idx = 0; idx != {{ size }}; idx++) { + jstring element = env->NewStringUTF({{ input }}[idx]); + env->SetObjectArrayElement({{ output }}, idx, element); + env->DeleteLocalRef(element); + } {% else %} - {{ unreachable_code() }} + {{ unreachable_code('Unsupported array type in convert_to_kotlin: ' ~ member.type.name.get()) }} {% endif %} {% elif member.type.category == 'object' %} jobject {{ output }};
diff --git a/generator/templates/art/api_kotlin_structure.kt b/generator/templates/art/api_kotlin_structure.kt index b19d99e..d44930c 100644 --- a/generator/templates/art/api_kotlin_structure.kt +++ b/generator/templates/art/api_kotlin_structure.kt
@@ -20,7 +20,7 @@ {% set ns = namespace(callback_count = 0, default_count = 0) %} {%- set members = [] -%} -{%- for member in kotlin_record_members(structure.members) -%} +{%- for member in kotlin_record_members(structure.members, structure.name.get()) -%} {%- if member.name.camelCase().endswith('Callback') -%} {%- set ns.callback_count = ns.callback_count + 1 -%} {%- endif -%}
diff --git a/generator/templates/art/api_kotlin_types.kt b/generator/templates/art/api_kotlin_types.kt index af471eb..29ba70a 100644 --- a/generator/templates/art/api_kotlin_types.kt +++ b/generator/templates/art/api_kotlin_types.kt
@@ -30,20 +30,24 @@ {%- set optional = arg.optional and not strip_optional %} {%- set default_value = arg.default_value %} {%- if type.category == 'kotlin type' -%} - {{ type.name.get() }} {#- The name *is* the type #} + {{ type.name.get() }}{{ '?' if optional }} {#- The name *is* the type #} {%- elif arg.type.name.get() == 'string view' -%} String{{ '?' if optional }} {%- elif type.name.get() == 'void' %} {{- assert(arg.length and arg.constant_length != 1) -}} {# void with length is binary data #} java.nio.ByteBuffer - {%- elif arg.length and arg.length != 'constant' %} + {%- elif arg.length and (arg.length != 'constant' or arg.constant_length != 1) %} {# * annotation can mean an array, e.g. an output argument #} {%- if type.category in ['callback function', 'callback info', 'function pointer', 'object', 'structure'] -%} - Array<{{ kotlin_name(type) }}> + Array<{{ kotlin_name(type) }}>{{ '?' if optional }} {%- elif type.category in ['bitmask', 'enum'] or type.name.get() in ['int', 'int32_t', 'uint32_t'] -%} - IntArray + IntArray{{ '?' if optional }} + {%- elif type.name.get() == 'float' -%} + FloatArray{{ '?' if optional }} + {%- elif type.name.get() == 'char' -%} + Array<String>{{ '?' if optional }} {%- else -%} - {{ unreachable_code() }} + {{ unreachable_code('Unsupported array type: ' + type.name.get()) }} {% endif %} {%- elif type.category in ['callback function', 'function pointer', 'object'] %} {{- kotlin_name(type) }}
diff --git a/generator/templates/art/kotlin_record_conversion.cpp b/generator/templates/art/kotlin_record_conversion.cpp index 894fb77..2919559 100644 --- a/generator/templates/art/kotlin_record_conversion.cpp +++ b/generator/templates/art/kotlin_record_conversion.cpp
@@ -26,28 +26,31 @@ //* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% from 'art/api_jni_types.cpp' import arg_to_jni_type, convert_to_kotlin, jni_signature with context %} -{% macro define_kotlin_record_structure(struct_name, members) %} +{% macro define_kotlin_record_structure(struct_name, members, structure_name=None) %} struct {{struct_name}} { - {% for member in kotlin_record_members(members) %} - //* HACK: Hardcode that ANativeWindow is a jlong instead of an actual pointer. Instead - //* of this, we should have manually written method that directly creates the - //* wgpu::Surface from the Java Surface. - {% if member.name.get() == "window" and member.type.name.get() == "void *"%} - jlong {{ as_varName(member.name) }}; - {% else %} - {{ arg_to_jni_type(member) }} {{ as_varName(member.name) }}; + {% for member in kotlin_record_members(members, structure_name) %} + {% if not member.skip_serialize %} + //* HACK: Hardcode that ANativeWindow is a jlong instead of an actual pointer. Instead + //* of this, we should have manually written method that directly creates the + //* wgpu::Surface from the Java Surface. + {% if member.name.get() == "window" and member.type.name.get() == "void *"%} + jlong {{ as_varName(member.name) }}; + {% else %} + {{ arg_to_jni_type(member) }} {{ as_varName(member.name) }}; + {% endif %} {% endif %} {% endfor%} }; {% endmacro %} -{% macro define_kotlin_to_struct_conversion(function_name, kotlin_name, struct_name, members,is_structure_converter=False) %} +{% macro define_kotlin_to_struct_conversion(function_name, kotlin_name, struct_name, members, structure_name=None, is_structure_converter=False) %} inline void {{function_name}}(JNIContext* c, const {{kotlin_name}}& inStruct, {{struct_name}}* outStruct) { JNIEnv* env = c->env; JNIClasses* classes = JNIClasses::getInstance(env); *outStruct = {}; - {% for member in kotlin_record_members(members) %} + {% for member in kotlin_record_members(members, structure_name) %} + {% if not member.skip_serialize %} { {% if member.type.category == 'callback function' %} if (inStruct.{{ as_varName(member.name) }}) @@ -122,7 +125,7 @@ {# Generate the C++ variable conversions (e.g. _status, _message) #} {%- for arg in kotlin_record_members(member.type.arguments) -%} - {{ convert_to_kotlin(arg.name.camelCase(), '_' + arg.name.camelCase(), 'input->' + arg.length.name.camelCase() if arg.length.name, arg) }} + {{ convert_to_kotlin(arg.name.camelCase(), '_' + arg.name.camelCase(), 'input->' + arg.length.name.camelCase() if arg.length and arg.length != 'constant' else (arg.constant_length | string if arg.length == 'constant' and arg.constant_length != 1 else None), arg) }} {%- set vName = '_' + arg.name.camelCase() -%} {%- set aName = arg.name.get() -%} {%- if aName == 'status' %} @@ -198,37 +201,60 @@ {{ unreachable_code() }} {% endif %} {% elif member.length %} - auto& outLength = outStruct->{{member.length.name.camelCase()}}; - {% if member.constant_length %} - {{ unreachable_code() }} - {% endif %} - //* Convert container, including the length field. - {% if member.type.name.get() == 'uint32_t' or member.type.category in ['bitmask', 'enum'] %} - out = reinterpret_cast<const {{ as_cType(member.type.name) }}*>(c->GetIntArrayElements(in)); - outLength = env->GetArrayLength(in); - {% elif member.type.name.get() == 'void' %} - out = env->GetDirectBufferAddress(in); - outLength = env->GetDirectBufferCapacity(in); - {% else %} - //* These container types are represented in Kotlin as arrays of objects. - outLength = env->GetArrayLength(in); - auto array = c->AllocArray<{{ as_cType(member.type.name) }}>(outLength); - out = array; - - {% if member.type.category == 'object' %} - jclass memberClass = classes->{{ member.type.name.camelCase() }}; - jmethodID getHandle = env->GetMethodID(memberClass, "getHandle", "()J"); + {% if member.length != 'constant' %} + auto& outLength = outStruct->{{member.length.name.camelCase()}}; + //* Convert container, including the length field. + {% if member.type.name.get() == 'uint32_t' or member.type.category in ['bitmask', 'enum'] %} + out = reinterpret_cast<const {{ as_cType(member.type.name) }}*>(c->GetIntArrayElements(in)); + outLength = env->GetArrayLength(in); + {% elif member.type.name.get() == 'void' %} + out = env->GetDirectBufferAddress(in); + outLength = env->GetDirectBufferCapacity(in); + {% elif member.type.name.get() == 'char' %} + outLength = env->GetArrayLength(in); + auto array = c->AllocArray<const char*>(outLength); for (int idx = 0; idx != outLength; idx++) { - jobject element = env->GetObjectArrayElement(in, idx); - array[idx] = reinterpret_cast<{{ as_cType(member.type.name) }}>( - env->CallLongMethod(element, getHandle)); + jstring element = static_cast<jstring>(env->GetObjectArrayElement(in, idx)); + array[idx] = c->GetStringUTFChars(element); } - {% elif member.type.category == 'structure' %} - for (int idx = 0; idx != outLength; idx++) { - ToNative(c, env, env->GetObjectArrayElement(in, idx), &array[idx]); + out = array; + {% else %} + //* These container types are represented in Kotlin as arrays of objects. + outLength = env->GetArrayLength(in); + auto array = c->AllocArray<{{ as_cType(member.type.name) }}>(outLength); + out = array; + + {% if member.type.category == 'object' %} + jclass memberClass = classes->{{ member.type.name.camelCase() }}; + jmethodID getHandle = env->GetMethodID(memberClass, "getHandle", "()J"); + for (int idx = 0; idx != outLength; idx++) { + jobject element = env->GetObjectArrayElement(in, idx); + array[idx] = reinterpret_cast<{{ as_cType(member.type.name) }}>( + env->CallLongMethod(element, getHandle)); + } + {% elif member.type.category == 'structure' %} + for (int idx = 0; idx != outLength; idx++) { + ToNative(c, env, env->GetObjectArrayElement(in, idx), &array[idx]); + } + {% else %} + {{ unreachable_code() }} + {% endif %} + {% endif %} + {% else %} + {% if member.type.name.get() == 'float' %} + jsize arrayLength = env->GetArrayLength(static_cast<jarray>(in)); + if (arrayLength == {{ member.constant_length }}) { + auto array = c->AllocArray<float>({{ member.constant_length }}); + env->GetFloatArrayRegion(static_cast<jfloatArray>(in), 0, {{ member.constant_length }}, array); + out = array; + } else { + // If the array length doesn't match the expected constant length, + // do not proceed to avoid potential crashes or uninitialized data. + // The out variable remains in its default-initialized state (e.g., nullptr). + return; } {% else %} - {{ unreachable_code() }} + {{ unreachable_code('Unsupported constant array type: ' ~ member.type.name.get()) }} {% endif %} {% endif %} //* From here members are single values. @@ -257,6 +283,7 @@ {{ unreachable_code() }} {% endif %} } + {% endif %} {% endfor -%} } {% endmacro %}
diff --git a/generator/templates/art/structures.cpp b/generator/templates/art/structures.cpp index db54bf8..31cea55 100644 --- a/generator/templates/art/structures.cpp +++ b/generator/templates/art/structures.cpp
@@ -108,16 +108,16 @@ jclass clz = classes->{{ structure.name.camelCase() }}; //* JNI signature needs to be built using the same logic used in the Kotlin structure spec. jmethodID ctor = env->GetMethodID(clz, "<init>", "( - {%- for member in kotlin_record_members(structure.members) %} + {%- for member in kotlin_record_members(structure.members, structure.name.get()) %} {{- jni_signature(member) -}} {%- endfor -%} {%- for structure in chain_children[structure.name.get()] -%} {{- jni_signature({'type': structure}) -}} {%- endfor %})V"); //* Each field converted using the individual value converter. - {% for member in kotlin_record_members(structure.members) %} + {% for member in kotlin_record_members(structure.members, structure.name.get()) %} {{ convert_to_kotlin('input->' + member.name.camelCase(), member.name.camelCase(), - 'input->' + member.length.name.camelCase() if member.length.name, + 'input->' + member.length.name.camelCase() if member.length and member.length != 'constant' else (member.constant_length | string if member.length == 'constant' and member.constant_length != 1 else None), member) | indent(4) -}} {% endfor %} //* Allow conversion of every child structure. @@ -145,7 +145,7 @@ jobject converted = env->NewObject( clz, ctor - {%- for member in kotlin_record_members(structure.members) %}, + {%- for member in kotlin_record_members(structure.members, structure.name.get()) %}, {%- if member.type.category == 'kotlin type' -%} nullptr {#- We can't make these. TODO(b/451995459): Don't even create the converter. #} {%- else -%} @@ -163,21 +163,23 @@ {% set Struct = as_cType(structure.name) %} {% set KotlinRecord = "KotlinRecord" + structure.name.CamelCase() %} - {{ define_kotlin_record_structure(KotlinRecord, structure.members)}} + {{ define_kotlin_record_structure(KotlinRecord, structure.members, structure.name.get())}} - {{ define_kotlin_to_struct_conversion("ConvertInternal", KotlinRecord, Struct, structure.members, is_structure_converter=True)}} + {{ define_kotlin_to_struct_conversion("ConvertInternal", KotlinRecord, Struct, structure.members, structure.name.get(), is_structure_converter=True)}} void ToNative(JNIContext* c, JNIEnv* env, jobject obj, {{ as_cType(structure.name) }}* converted) { JNIClasses* classes = JNIClasses::getInstance(env); jclass clz = classes->{{ structure.name.camelCase() }}; //* Use getters to fill in the Kotlin record that will get converted to our struct. {{KotlinRecord}} kotlinRecord; - {% for member in kotlin_record_members(structure.members) %} - { - {% set prefix = "is" if member.type.name.get() == "bool" else "get" %} - jmethodID getter = env->GetMethodID(clz, "{{prefix}}{{member.name.CamelCase()}}", "(){{jni_signature(member)}}"); - CallGetter(env, getter, obj, &kotlinRecord.{{as_varName(member.name)}}); - } + {% for member in kotlin_record_members(structure.members, structure.name.get()) %} + {% if not member.skip_serialize %} + { + {% set prefix = "is" if member.type.name.get() == "bool" else "get" %} + jmethodID getter = env->GetMethodID(clz, "{{prefix}}{{member.name.CamelCase()}}", "(){{jni_signature(member)}}"); + CallGetter(env, getter, obj, &kotlinRecord.{{as_varName(member.name)}}); + } + {% endif %} {% endfor %} //* Fill all struct members from the Kotlin record.
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json index 45b81de..85d1a75 100644 --- a/src/dawn/dawn.json +++ b/src/dawn/dawn.json
@@ -232,7 +232,7 @@ ] }, "dawn toggles descriptor": { - "tags": ["dawn", "native"], + "tags": ["dawn", "native", "art_experimental"], "category": "structure", "chained": "in", "chain roots": ["instance descriptor", "request adapter options", "device descriptor"], @@ -1356,7 +1356,7 @@ { "name": "create external texture", "returns": "external texture", - "tags": ["dawn"], + "tags": ["dawn", "art_experimental"], "args": [ {"name": "external texture descriptor", "type": "external texture descriptor", "annotation": "const*"} ] @@ -1364,7 +1364,7 @@ { "name": "create error external texture", "returns": "external texture", - "tags": ["dawn"] + "tags": ["dawn", "art_experimental"] }, { "name": "create pipeline layout", @@ -1799,7 +1799,7 @@ }, "extent 2D": { "category": "structure", - "tags": ["dawn"], + "tags": ["dawn", "art_experimental"], "members": [ {"name": "width", "type": "uint32_t"}, {"name": "height", "type": "uint32_t"} @@ -1825,7 +1825,7 @@ }, { "name": "destroy", - "tags": ["dawn"] + "tags": ["dawn", "art_experimental"] }, { "name": "expire", @@ -1839,7 +1839,7 @@ }, "external texture rotation": { "category": "enum", - "tags": ["dawn"], + "tags": ["dawn", "art_experimental"], "_comment": "Angles are clockwise rotation degrees and not trigonometric.", "values": [ {"value": 1, "name": "rotate 0 degrees"}, @@ -1851,7 +1851,7 @@ "external texture descriptor": { "category": "structure", "extensible": "in", - "tags": ["dawn"], + "tags": ["dawn", "art_experimental"], "members": [ {"name": "label", "type": "string view", "optional": true}, {"name": "plane 0", "type": "texture view"}, @@ -2516,7 +2516,7 @@ {"value": 28, "name": "multi planar format p410", "tags": ["dawn"]}, {"value": 29, "name": "shared texture memory vk dedicated allocation", "tags": ["dawn", "native"]}, - {"value": 30, "name": "shared texture memory a hardware buffer", "tags": ["dawn", "native"]}, + {"value": 30, "name": "shared texture memory a hardware buffer", "tags": ["dawn", "native", "art_experimental"]}, {"value": 31, "name": "shared texture memory dma buf", "tags": ["dawn", "native"]}, {"value": 32, "name": "shared texture memory opaque FD", "tags": ["dawn", "native"]}, {"value": 33, "name": "shared texture memory zircon handle", "tags": ["dawn", "native"]}, @@ -2525,13 +2525,13 @@ {"value": 36, "name": "shared texture memory IO surface", "tags": ["dawn", "native"]}, {"value": 37, "name": "shared texture memory EGL image", "tags": ["dawn", "native"]}, {"value": 38, "name": "shared fence vk semaphore opaque FD", "tags": ["dawn", "native"]}, - {"value": 39, "name": "shared fence sync FD", "tags": ["dawn", "native"]}, + {"value": 39, "name": "shared fence sync FD", "tags": ["dawn", "native", "art_experimental"]}, {"value": 40, "name": "shared fence vk semaphore zircon handle", "tags": ["dawn", "native"]}, {"value": 41, "name": "shared fence DXGI shared handle", "tags": ["dawn", "native"]}, {"value": 42, "name": "shared fence MTL shared event", "tags": ["dawn", "native"]}, {"value": 43, "name": "shared buffer memory D3D12 resource", "tags": ["dawn", "native"]}, {"value": 44, "name": "static samplers", "tags": ["dawn"]}, - {"value": 45, "name": "y cb cr vulkan samplers", "tags": ["dawn"]}, + {"value": 45, "name": "y cb cr vulkan samplers", "tags": ["dawn", "art_experimental"]}, {"value": 46, "name": "shader module compilation options", "tags": ["dawn"]}, {"value": 47, "name": "dawn load resolve texture", "tags": ["dawn"]}, @@ -2548,7 +2548,7 @@ {"value": 58, "name": "chromium experimental sampling resource table", "tags": ["dawn"]}, {"value": 59, "name": "atomic vec2u min max", "tags": ["dawn"]}, {"value": 60, "name": "unorm16 formats for external texture", "tags": ["dawn"]}, - {"value": 61, "name": "opaque y cb cr android for external texture", "tags": ["dawn"]}, + {"value": 61, "name": "opaque y cb cr android for external texture", "tags": ["dawn", "art_experimental"]}, {"value": 62, "name": "unorm16 filterable", "tags": ["dawn"]}, {"value": 63, "name": "render pass render area", "tags": ["dawn"]}, {"value": 64, "name": "adapter properties drm", "tags": ["dawn", "native"]}, @@ -2853,7 +2853,7 @@ }, "origin 2D": { "category": "structure", - "tags": ["dawn"], + "tags": ["dawn", "art_experimental"], "members": [ {"name": "x", "type": "uint32_t", "default": "0"}, {"name": "y", "type": "uint32_t", "default": "0"} @@ -4097,7 +4097,7 @@ {"value": 7, "name": "dawn cache device descriptor", "tags": ["dawn", "native"]}, {"value": 8, "name": "dawn adapter properties power preference", "tags": ["dawn", "native"]}, {"value": 9, "name": "dawn buffer descriptor error info from wire client", "tags": ["dawn"]}, - {"value": 10, "name": "dawn toggles descriptor", "tags": ["dawn", "native"]}, + {"value": 10, "name": "dawn toggles descriptor", "tags": ["dawn", "native", "art_experimental"]}, {"value": 11, "name": "dawn shader module SPIRV options descriptor", "tags": ["dawn"]}, {"value": 12, "name": "request adapter options LUID", "tags": ["dawn", "native"]}, {"value": 13, "name": "request adapter options get GL proc", "tags": ["dawn", "native"]},
diff --git a/src/dawn/dawn_kotlin.json b/src/dawn/dawn_kotlin.json index 9761cbe..c97ebce 100644 --- a/src/dawn/dawn_kotlin.json +++ b/src/dawn/dawn_kotlin.json
@@ -37,6 +37,7 @@ "double": "jdouble", "float": "jfloat", "size_t": "jlong", + "int": "jint", "int32_t": "jint", "uint16_t": "jshort", "uint32_t": "jint", @@ -50,6 +51,7 @@ "bool": "Z", "double": "D", "float": "F", + "int": "I", "int16_t": "S", "int32_t": "I", "int64_t": "J", @@ -110,6 +112,31 @@ }, "future wait info": { "omitted": true + }, + "external texture descriptor": { + "exclude_members": [ + "plane 0", + "apparent size", + "src transfer function parameters", + "dst transfer function parameters", + "gamut conversion matrix", + "do yuv to rgb conversion only", + "yuv to rgb conversion matrix" + ], + "additional_members": [ + { + "name": "srcColorSpace", + "type": "color space dawn", + "category": "structure", + "optional": false + }, + { + "name": "dstColorSpace", + "type": "predefined color space", + "category": "kotlin type", + "optional": false + } + ] } }, "enums": {
diff --git a/tools/android/BUILD.gn b/tools/android/BUILD.gn index 66f39811..bbff405 100644 --- a/tools/android/BUILD.gn +++ b/tools/android/BUILD.gn
@@ -94,6 +94,7 @@ "java/androidx/webgpu/ErrorFilter.kt", "java/androidx/webgpu/ErrorType.kt", "java/androidx/webgpu/Exceptions.kt", + "java/androidx/webgpu/ExternalTextureRotation.kt", "java/androidx/webgpu/FeatureLevel.kt", "java/androidx/webgpu/FeatureName.kt", "java/androidx/webgpu/FilterMode.kt", @@ -128,19 +129,23 @@ "java/androidx/webgpu/GPUComputePipelineDescriptor.kt", "java/androidx/webgpu/GPUComputeState.kt", "java/androidx/webgpu/GPUConstantEntry.kt", + "java/androidx/webgpu/GPUDawnTogglesDescriptor.kt", "java/androidx/webgpu/GPUDepthStencilState.kt", "java/androidx/webgpu/GPUDevice.kt", "java/androidx/webgpu/GPUDeviceDescriptor.kt", + "java/androidx/webgpu/GPUExtent2D.kt", "java/androidx/webgpu/GPUExtent3D.kt", "java/androidx/webgpu/GPUExternalTexture.kt", "java/androidx/webgpu/GPUExternalTextureBindingEntry.kt", "java/androidx/webgpu/GPUExternalTextureBindingLayout.kt", + "java/androidx/webgpu/GPUExternalTextureDescriptor.kt", "java/androidx/webgpu/GPUFragmentState.kt", "java/androidx/webgpu/GPUInstance.kt", "java/androidx/webgpu/GPUInstanceDescriptor.kt", "java/androidx/webgpu/GPUInstanceLimits.kt", "java/androidx/webgpu/GPULimits.kt", "java/androidx/webgpu/GPUMultisampleState.kt", + "java/androidx/webgpu/GPUOrigin2D.kt", "java/androidx/webgpu/GPUOrigin3D.kt", "java/androidx/webgpu/GPUPassTimestampWrites.kt", "java/androidx/webgpu/GPUPipelineLayout.kt",
diff --git a/tools/android/webgpu/src/test/java/androidx/webgpu/MappedNamedConstantsTest.kt b/tools/android/webgpu/src/test/java/androidx/webgpu/MappedNamedConstantsTest.kt index 809cbc3..6ff46b3 100644 --- a/tools/android/webgpu/src/test/java/androidx/webgpu/MappedNamedConstantsTest.kt +++ b/tools/android/webgpu/src/test/java/androidx/webgpu/MappedNamedConstantsTest.kt
@@ -61,6 +61,7 @@ DeviceLostReason::class, ErrorFilter::class, ErrorType::class, + ExternalTextureRotation::class, FeatureLevel::class, FeatureName::class, FilterMode::class,