Kotlin methods return binary data in ByteBuffers. This removes the need for handwritten versions of getMappedRange and getConstMappedRange. Having said that, we might want to supply a helper extension for clients, that can supply the size parameter and automatically call the const or non-const version appropriately. Bug: 330293683 Change-Id: I57282735cb65cb719c98cf20b37621714bd06d4a Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/191621 Commit-Queue: Jim Blackler <jimblackler@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/generator/dawn_json_generator.py b/generator/dawn_json_generator.py index eb5d614..64d11af 100644 --- a/generator/dawn_json_generator.py +++ b/generator/dawn_json_generator.py
@@ -813,9 +813,6 @@ return True def include_method(method): - if method.return_type.name.get() in ['void *', 'void const *']: - # All methods that return binary data are handwritten. - return False if method.return_type.category == 'function pointer': # Kotlin doesn't support returning functions. return False
diff --git a/generator/templates/art/api_kotlin_object.kt b/generator/templates/art/api_kotlin_object.kt index 021ab3b..fe72b9e 100644 --- a/generator/templates/art/api_kotlin_object.kt +++ b/generator/templates/art/api_kotlin_object.kt
@@ -25,6 +25,8 @@ //* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package {{ kotlin_package }} + +import java.nio.ByteBuffer {% from 'art/api_kotlin_types.kt' import kotlin_type_declaration, kotlin_definition with context %} class {{ obj.name.CamelCase() }}(val handle: Long): AutoCloseable {
diff --git a/generator/templates/art/api_kotlin_types.kt b/generator/templates/art/api_kotlin_types.kt index 14f8103..d37e0ad 100644 --- a/generator/templates/art/api_kotlin_types.kt +++ b/generator/templates/art/api_kotlin_types.kt
@@ -103,6 +103,8 @@ {% endif %} {%- elif type.name.get() == 'void' %} {{- 'Long' if arg.annotation == '*' else 'Unit' }} + {%- elif type.name.get() in ['void *', 'void const *'] %} + ByteBuffer {%- else -%} {{ unreachable_code() }} {%- endif %}
diff --git a/generator/templates/art/methods.cpp b/generator/templates/art/methods.cpp index 79ca066..4294eba 100644 --- a/generator/templates/art/methods.cpp +++ b/generator/templates/art/methods.cpp
@@ -40,6 +40,27 @@ jobject callback; }; +jobject toByteBuffer(JNIEnv *env, const void* address, jlong size) { + if (!address) { + return nullptr; + } + jclass byteBufferClass = env->FindClass("java/nio/ByteBuffer"); + + //* Dawn always uses little endian format, so we pre-convert for the client's convenience. + jclass byteOrderClass = env->FindClass("java/nio/ByteOrder"); + jobject littleEndian = env->NewGlobalRef(env->GetStaticObjectField( + byteOrderClass, env->GetStaticFieldID(byteOrderClass, "LITTLE_ENDIAN", + "Ljava/nio/ByteOrder;"))); + + jobject byteBuffer = env->NewDirectByteBuffer(const_cast<void *>(address), size); + + env->CallObjectMethod( + byteBuffer, env->GetMethodID(byteBufferClass, "order", + "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"), + littleEndian); + return byteBuffer; +} + {% macro render_method(method, object) %} //* A JNI-external method is built with the JNI signature expected to match the host Kotlin. DEFAULT extern "C" @@ -271,6 +292,8 @@ jclass returnClass = env->FindClass("{{ jni_name(method.return_type) }}"); auto constructor = env->GetMethodID(returnClass, "<init>", "(J)V"); return env->NewObject(returnClass, constructor, reinterpret_cast<jlong>(result)); + {% elif method.return_type.name.get() in ['void const *', 'void *'] %} + return toByteBuffer(env, result, size); {% elif method.return_type.name.get() != 'void' %} return result; //* Primitives are implicitly converted by JNI. {% endif %}
diff --git a/src/dawn/dawn_kotlin.json b/src/dawn/dawn_kotlin.json index 1e9dfa0..d205550 100644 --- a/src/dawn/dawn_kotlin.json +++ b/src/dawn/dawn_kotlin.json
@@ -39,6 +39,8 @@ "size_t": "jlong", "uint32_t": "jint", "uint64_t": "jlong", + "void *": "jobject", + "void const *": "jobject", "void": "void" } }