Include Android Samples to Dawn Adding three sample Android Applications that use Dawn: 1. Render HelloTriangle using C API 2. Render HelloTriangle using C++ API 3. Compute Sample using C++ API Follow "Building Instructions for Android Application Samples" in go/dawn-on-android-samples to test the samples locally. Change-Id: Ia0a257d9b3a35fa34f93bcdaee29bd609c386a01
diff --git a/CMakeLists.txt b/CMakeLists.txt index 69066a7..791c449 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -87,8 +87,9 @@ # Default values for the backend-enabling options set(USE_WAYLAND OFF) set(USE_X11 OFF) +set(BUILD_ANDROID_SAMPLES OFF) -if(UNIX) +if (UNIX AND NOT ANDROID) set(USE_X11 ON) endif() @@ -102,11 +103,13 @@ # Current examples are depend on GLFW if (SAMPLES_SUPPORTS_GLFW_FOR_WINDOWING) set(BUILD_SAMPLES ON) +elseif (ANDROID) + set(BUILD_ANDROID_SAMPLES ON) endif() option_if_not_defined(SAMPLES_USE_GLFW "Enable compilation of the GLFW windowing utils" ${SAMPLES_SUPPORTS_GLFW_FOR_WINDOWING}) -if (NOT SAMPLES_USE_GLFW) +if (NOT SAMPLES_USE_GLFW AND NOT ANDROID) message(SEND_ERROR "Dawn samples require GLFW") endif() @@ -119,8 +122,10 @@ option_if_not_defined(DAWN_USE_WAYLAND "Enable support for Wayland surface" ${USE_WAYLAND}) option_if_not_defined(DAWN_USE_X11 "Enable support for X11 surface" ${USE_X11}) option_if_not_defined(DAWN_FETCH_DEPENDENCIES "Use fetch_dawn_dependencies.py as an alternative to using depot_tools" ON) +option_if_not_defined(DAWN_BUILD_ANDROID_SAMPLES "Enables building Dawn's samples" ${BUILD_ANDROID_SAMPLES}) message(STATUS "Samples build GLFW support: ${SAMPLES_USE_GLFW}") +message(STATUS "Dawn build Android samples: ${DAWN_BUILD_ANDROID_SAMPLES}") message(STATUS "Using python3") find_package(PythonInterp 3 REQUIRED)
diff --git a/src/samples/Animometer.cpp b/src/samples/Animometer.cpp index 6a992e9..895d0bd 100644 --- a/src/samples/Animometer.cpp +++ b/src/samples/Animometer.cpp
@@ -29,7 +29,7 @@ #include <cstdlib> #include <vector> -#include "dawn/samples/SampleUtils.h" +#include "utils/SampleUtils.h" #include "dawn/utils/ComboRenderPipelineDescriptor.h" #include "dawn/utils/SystemUtils.h"
diff --git a/src/samples/CHelloTriangle.cpp b/src/samples/CHelloTriangle.cpp index 67252ba..5b7a237 100644 --- a/src/samples/CHelloTriangle.cpp +++ b/src/samples/CHelloTriangle.cpp
@@ -24,8 +24,7 @@ // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // 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. - -#include "dawn/samples/SampleUtils.h" +#include "utils/SampleUtils.h" #include "dawn/utils/SystemUtils.h" #include "dawn/utils/WGPUHelpers.h"
diff --git a/src/samples/CMakeLists.txt b/src/samples/CMakeLists.txt index 4a1f3dd..327772a 100644 --- a/src/samples/CMakeLists.txt +++ b/src/samples/CMakeLists.txt
@@ -25,27 +25,14 @@ # 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. -add_library(dawn_sample_utils STATIC ${SAMPLES_PLACEHOLDER_FILE}) -target_include_directories(dawn_sample_utils INTERFACE - "${SAMPLES_SRC_DIR}" -) +add_subdirectory(utils) -common_compile_options(dawn_sample_utils) -target_sources(dawn_sample_utils PRIVATE - "SampleUtils.cpp" - "SampleUtils.h" -) -target_link_libraries(dawn_sample_utils PUBLIC - dawn_internal_config - dawncpp - dawn_proc - dawn_common - dawn_glfw - dawn_native - dawn_wire - dawn_utils - glfw -) +if (DAWN_BUILD_ANDROID_SAMPLES) + add_subdirectory(android/chellotriangle) + add_subdirectory(android/cpphellotriangle) + add_subdirectory(android/computeboids) + +else() add_executable(CppHelloTriangle "CppHelloTriangle.cpp") common_compile_options(CppHelloTriangle) @@ -62,3 +49,5 @@ add_executable(Animometer "Animometer.cpp") common_compile_options(Animometer) target_link_libraries(Animometer dawn_sample_utils) + +endif()
diff --git a/src/samples/ComputeBoids.cpp b/src/samples/ComputeBoids.cpp index 6062aff..a8074cf 100644 --- a/src/samples/ComputeBoids.cpp +++ b/src/samples/ComputeBoids.cpp
@@ -30,7 +30,7 @@ #include <random> #include <vector> -#include "dawn/samples/SampleUtils.h" +#include "utils/SampleUtils.h" #include "dawn/utils/ComboRenderPipelineDescriptor.h" #include "dawn/utils/SystemUtils.h"
diff --git a/src/samples/CppHelloTriangle.cpp b/src/samples/CppHelloTriangle.cpp index b1b47a5..2303f9e 100644 --- a/src/samples/CppHelloTriangle.cpp +++ b/src/samples/CppHelloTriangle.cpp
@@ -27,7 +27,7 @@ #include <vector> -#include "dawn/samples/SampleUtils.h" +#include "utils/SampleUtils.h" #include "dawn/utils/ComboRenderPipelineDescriptor.h" #include "dawn/utils/SystemUtils.h"
diff --git a/src/samples/SampleUtils.h b/src/samples/SampleUtils.h deleted file mode 100644 index fb7e289..0000000 --- a/src/samples/SampleUtils.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright 2017 The Dawn & Tint Authors -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// 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. - -#ifndef SRC_DAWN_SAMPLES_SAMPLEUTILS_H_ -#define SRC_DAWN_SAMPLES_SAMPLEUTILS_H_ - -#include "dawn/webgpu_cpp.h" - -bool InitSample(int argc, const char** argv); -void DoFlush(); -bool ShouldQuit(); - -struct GLFWwindow; -struct GLFWwindow* GetGLFWWindow(); - -wgpu::Device CreateCppDawnDevice(); -wgpu::TextureFormat GetPreferredSwapChainTextureFormat(); -wgpu::SwapChain GetSwapChain(); -wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device); -void ProcessEvents(); - -#endif // SRC_DAWN_SAMPLES_SAMPLEUTILS_H_
diff --git a/src/samples/android/.gitignore b/src/samples/android/.gitignore new file mode 100644 index 0000000..583335e --- /dev/null +++ b/src/samples/android/.gitignore
@@ -0,0 +1,15 @@ +*.iml +/.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties
diff --git a/src/samples/android/build.gradle b/src/samples/android/build.gradle new file mode 100644 index 0000000..a100ce0 --- /dev/null +++ b/src/samples/android/build.gradle
@@ -0,0 +1,5 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id 'com.android.application' version '8.0.2' apply false + id 'com.android.library' version '8.0.2' apply false +} \ No newline at end of file
diff --git a/src/samples/android/chellotriangle/.gitignore b/src/samples/android/chellotriangle/.gitignore new file mode 100644 index 0000000..ca1d807 --- /dev/null +++ b/src/samples/android/chellotriangle/.gitignore
@@ -0,0 +1,16 @@ +*.iml +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +/.cxx +local.properties +build/
diff --git a/src/samples/android/chellotriangle/CMakeLists.txt b/src/samples/android/chellotriangle/CMakeLists.txt new file mode 100644 index 0000000..6a6a2cf --- /dev/null +++ b/src/samples/android/chellotriangle/CMakeLists.txt
@@ -0,0 +1,13 @@ +add_library(chellotriangle MODULE + src/main/cpp/CHelloTriangle.cpp + src/main/cpp/RendererC.cc + src/main/cpp/RendererC.h +) + +target_include_directories(chellotriangle PRIVATE SAMPLES_SRC_UTILS_DIR) + +target_link_options(chellotriangle PUBLIC + "-u Java_com_google_androidgamesdk_GameActivity_initializeNativeCode" +) + +target_link_libraries(chellotriangle dawn_sample_utils) \ No newline at end of file
diff --git a/src/samples/android/chellotriangle/build.gradle b/src/samples/android/chellotriangle/build.gradle new file mode 100644 index 0000000..22ae582 --- /dev/null +++ b/src/samples/android/chellotriangle/build.gradle
@@ -0,0 +1,46 @@ +plugins { + id 'com.android.application' +} + +android { + namespace 'com.google.chellotriangle' + compileSdk 33 + + defaultConfig { + applicationId "com.google.chellotriangle" + minSdk 30 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + debuggable true + jniDebuggable true + } + debug { + debuggable true + jniDebuggable true + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation project(':common') + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.games:games-activity:1.2.2' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +}
diff --git a/src/samples/android/chellotriangle/src/main/AndroidManifest.xml b/src/samples/android/chellotriangle/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ae22342 --- /dev/null +++ b/src/samples/android/chellotriangle/src/main/AndroidManifest.xml
@@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> + + <application + android:allowBackup="true" + android:dataExtractionRules="@xml/data_extraction_rules" + android:fullBackupContent="@xml/backup_rules" + android:icon="@mipmap/ic_launcher" + android:label= "chellotriangle" + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsRtl="true" + android:theme="@style/Theme.Game_activity" + tools:targetApi="31"> + <activity + android:name=".MainActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + + <meta-data + android:name="android.app.lib_name" + android:value="chellotriangle" /> + </activity> + </application> + +</manifest> \ No newline at end of file
diff --git a/src/samples/android/chellotriangle/src/main/cpp/CHelloTriangle.cpp b/src/samples/android/chellotriangle/src/main/cpp/CHelloTriangle.cpp new file mode 100644 index 0000000..b50eaa6 --- /dev/null +++ b/src/samples/android/chellotriangle/src/main/cpp/CHelloTriangle.cpp
@@ -0,0 +1,56 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include <game-activity/GameActivity.cpp> +#include "RendererC.h" // NOLINT + +extern "C" { +#include <game-activity/native_app_glue/android_native_app_glue.c> // NOLINT + +void handle_cmd(android_app* pApp, int32_t cmd) { + switch (cmd) { + case APP_CMD_INIT_WINDOW: + // A new window is created, associate a renderer with it. + pApp->userData = new RendererC(pApp); + break; + case APP_CMD_TERM_WINDOW: + // The window is being destroyed. Use this to clean up your userData to avoid leaking + // resources. + if (pApp->userData) { + auto* pRenderer = reinterpret_cast<RendererC*>(pApp->userData); + pApp->userData = nullptr; + delete pRenderer; + } + break; + default: + break; + } +} + +void android_main(android_app* pApp) { + pApp->onAppCmd = handle_cmd; + int events; + android_poll_source* pSource; + do { + if (ALooper_pollAll(0, nullptr, &events, reinterpret_cast<void**>(&pSource)) >= 0) { + if (pSource) { + pSource->process(pApp, pSource); + } + } + if (pApp->userData) { + auto* pRenderer = reinterpret_cast<RendererC*>(pApp->userData); + pRenderer->GameLoop(); + } + } while (!pApp->destroyRequested); +} +}
diff --git a/src/samples/android/chellotriangle/src/main/cpp/RendererC.cc b/src/samples/android/chellotriangle/src/main/cpp/RendererC.cc new file mode 100644 index 0000000..6e6ab3e --- /dev/null +++ b/src/samples/android/chellotriangle/src/main/cpp/RendererC.cc
@@ -0,0 +1,115 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include "RendererC.h" // NOLINT +#include "dawn/common/Log.h" + +void RendererC::Init() { + device = CreateCppDawnDeviceForAndroid(androidDesc).MoveToCHandle(); + queue = wgpuDeviceGetQueue(device); + swapChain = GetSwapChain().MoveToCHandle(); + + const char* shaderSource = R"( + @vertex fn vs_main(@builtin(vertex_index) i : u32) -> + @builtin(position) vec4f { + var p = vec2f(0.0, 0.0); + if (i == 0u) { + p = vec2f(-0.5, -0.5); + } else if (i == 1u) { + p = vec2f(0.5, -0.5); + } else { + p = vec2f(0.0, 0.5); + } + return vec4f(p, 0.0, 1.0); + } + + @fragment fn fs_main() -> @location(0) vec4f { + return vec4f(0.0, 0.4, 1.0, 1.0); + } + )"; + + WGPUShaderModuleWGSLDescriptor shaderCodeDesc = {}; + shaderCodeDesc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; + shaderCodeDesc.code = shaderSource; + WGPUShaderModuleDescriptor shaderDesc = {}; + shaderDesc.nextInChain = &shaderCodeDesc.chain; + + WGPUShaderModule shaderModule = wgpuDeviceCreateShaderModule(device, &shaderDesc); + WGPURenderPipelineDescriptor pipelineDesc = {}; + + // Vertex shader + pipelineDesc.vertex.module = shaderModule; + pipelineDesc.vertex.entryPoint = "vs_main"; + pipelineDesc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + + // Fragment shader + WGPUFragmentState fragmentState = {}; + pipelineDesc.fragment = &fragmentState; + fragmentState.module = shaderModule; + fragmentState.entryPoint = "fs_main"; + + + WGPUColorTargetState colorTarget = {}; + colorTarget.format = static_cast<WGPUTextureFormat>(GetPreferredSwapChainTextureFormat()); + colorTarget.writeMask = WGPUColorWriteMask_All; + + fragmentState.targetCount = 1; + fragmentState.targets = &colorTarget; + pipelineDesc.multisample.count = 1; + pipelineDesc.multisample.mask = ~0u; + pipelineDesc.multisample.alphaToCoverageEnabled = false; + pipeline = wgpuDeviceCreateRenderPipeline(device, &pipelineDesc); +} + +void RendererC::Frame() { + WGPUTextureView nextTexture = wgpuSwapChainGetCurrentTextureView(swapChain); + if (!nextTexture) { + dawn::ErrorLog() << "Cannot acquire next swap chain texture"; + return; + } + + WGPURenderPassColorAttachment renderPassColorAttachment = {}; + renderPassColorAttachment.view = nextTexture; + renderPassColorAttachment.loadOp = WGPULoadOp_Clear; + renderPassColorAttachment.storeOp = WGPUStoreOp_Store; + renderPassColorAttachment.clearValue = WGPUColor{0.9, 0.1, 0.2, 1.0}; + + WGPURenderPassDescriptor renderPassDesc = {}; + renderPassDesc.colorAttachmentCount = 1; + renderPassDesc.colorAttachments = &renderPassColorAttachment; + + WGPUCommandEncoderDescriptor commandEncoderDesc = {}; + commandEncoderDesc.label = "Command Encoder"; + WGPUCommandEncoder encoder = wgpuDeviceCreateCommandEncoder(device, &commandEncoderDesc); + WGPURenderPassEncoder renderPass = wgpuCommandEncoderBeginRenderPass(encoder, &renderPassDesc); + wgpuRenderPassEncoderSetPipeline(renderPass, pipeline); + wgpuRenderPassEncoderDraw(renderPass, 3, 1, 0, 0); + wgpuRenderPassEncoderEnd(renderPass); + + wgpuTextureViewRelease(nextTexture); + + WGPUCommandBufferDescriptor cmdBufferDescriptor = {}; + cmdBufferDescriptor.label = "Command buffer"; + + WGPUCommandBuffer command = wgpuCommandEncoderFinish(encoder, &cmdBufferDescriptor); + wgpuQueueSubmit(queue, 1, &command); + wgpuSwapChainPresent(swapChain); +} + +void RendererC::GameLoop() { + if (!deviceInitialised) { + Init(); + deviceInitialised = true; + } + Frame(); +}
diff --git a/src/samples/android/chellotriangle/src/main/cpp/RendererC.h b/src/samples/android/chellotriangle/src/main/cpp/RendererC.h new file mode 100644 index 0000000..b8e408e --- /dev/null +++ b/src/samples/android/chellotriangle/src/main/cpp/RendererC.h
@@ -0,0 +1,42 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include <game-activity/native_app_glue/android_native_app_glue.h> +#include "../../../../../utils/SampleUtils.h" + +#ifndef APP_SRC_MAIN_CPP2_RENDERER_H_ +#define APP_SRC_MAIN_CPP2_RENDERER_H_ + +class RendererC { + public: + WGPUDevice device; + WGPUSwapChain swapChain; + WGPURenderPipeline pipeline; + WGPUQueue queue; + WGPUInstance instance; + WGPUInstanceDescriptor desc; + wgpu::SurfaceDescriptorFromAndroidNativeWindow androidDesc; + bool deviceInitialised; + + explicit RendererC(android_app* mApp) { + deviceInitialised = false; + androidDesc.window = mApp->window; + androidDesc.sType = wgpu::SType::SurfaceDescriptorFromAndroidNativeWindow; + } + + void Init(); + void Frame(); + void GameLoop(); +}; + +#endif // APP_SRC_MAIN_CPP2_RENDERER_H_
diff --git a/src/samples/android/chellotriangle/src/main/java/com/google/chellotriangle/MainActivity.java b/src/samples/android/chellotriangle/src/main/java/com/google/chellotriangle/MainActivity.java new file mode 100644 index 0000000..499e0d8 --- /dev/null +++ b/src/samples/android/chellotriangle/src/main/java/com/google/chellotriangle/MainActivity.java
@@ -0,0 +1,28 @@ +package com.google.chellotriangle; + +import android.view.View; + +import com.google.androidgamesdk.GameActivity; + +public class MainActivity extends GameActivity { + static { + System.loadLibrary("chellotriangle"); + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + + if (hasFocus) { + hideSystemUi(); + } + } + + private void hideSystemUi() { + View decorView = getWindow().getDecorView(); + decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN); + } +}
diff --git a/src/samples/android/common/.gitignore b/src/samples/android/common/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/src/samples/android/common/.gitignore
@@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties
diff --git a/src/samples/android/common/build.gradle b/src/samples/android/common/build.gradle new file mode 100644 index 0000000..6dce99f --- /dev/null +++ b/src/samples/android/common/build.gradle
@@ -0,0 +1,57 @@ +plugins { + id 'com.android.library' +} + +android { + namespace 'com.google.common' + compileSdk 33 + + defaultConfig { + minSdk 30 + targetSdk 33 + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles "consumer-rules.pro" + + externalNativeBuild { + cmake { + targets "cpphellotriangle", "chellotriangle", "computeboids" + } + } + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + debug { + debuggable true + jniDebuggable true + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + buildFeatures { + prefab true + } + + externalNativeBuild { + cmake { + path file('../../../../CMakeLists.txt') + version '3.22.1' + } + } +} + +dependencies { + implementation 'androidx.games:games-activity:1.2.2' + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +} \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/drawable-v24/ic_launcher_foreground.xml b/src/samples/android/common/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..966abaf --- /dev/null +++ b/src/samples/android/common/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:aapt="http://schemas.android.com/aapt" + android:width="108dp" + android:height="108dp" + android:viewportHeight="108" + android:viewportWidth="108"> + <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> + <aapt:attr name="android:fillColor"> + <gradient + android:endX="85.84757" + android:endY="92.4963" + android:startX="42.9492" + android:startY="49.59793" + android:type="linear"> + <item + android:color="#44000000" + android:offset="0.0" /> + <item + android:color="#00000000" + android:offset="1.0" /> + </gradient> + </aapt:attr> + </path> + <path + android:fillColor="#FFFFFF" + android:fillType="nonZero" + android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" + android:strokeColor="#00000000" + android:strokeWidth="1" /> +</vector> \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/drawable/ic_launcher_background.xml b/src/samples/android/common/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..61bb79e --- /dev/null +++ b/src/samples/android/common/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="108dp" + android:height="108dp" + android:viewportHeight="108" + android:viewportWidth="108"> + <path + android:fillColor="#3DDC84" + android:pathData="M0,0h108v108h-108z" /> + <path + android:fillColor="#00000000" + android:pathData="M9,0L9,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M19,0L19,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M29,0L29,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M39,0L39,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M49,0L49,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M59,0L59,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M69,0L69,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M79,0L79,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M89,0L89,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M99,0L99,108" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,9L108,9" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,19L108,19" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,29L108,29" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,39L108,39" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,49L108,49" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,59L108,59" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,69L108,69" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,79L108,79" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,89L108,89" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M0,99L108,99" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M19,29L89,29" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M19,39L89,39" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M19,49L89,49" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M19,59L89,59" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M19,69L89,69" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M19,79L89,79" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M29,19L29,89" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M39,19L39,89" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M49,19L49,89" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M59,19L59,89" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M69,19L69,89" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> + <path + android:fillColor="#00000000" + android:pathData="M79,19L79,89" + android:strokeColor="#33FFFFFF" + android:strokeWidth="0.8" /> +</vector>
diff --git a/src/samples/android/common/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/src/samples/android/common/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..5ad9ce1 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@drawable/ic_launcher_background" /> + <foreground android:drawable="@drawable/ic_launcher_foreground" /> + <monochrome android:drawable="@drawable/ic_launcher_foreground" /> +</adaptive-icon> \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/src/samples/android/common/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..5ad9ce1 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@drawable/ic_launcher_background" /> + <foreground android:drawable="@drawable/ic_launcher_foreground" /> + <monochrome android:drawable="@drawable/ic_launcher_foreground" /> +</adaptive-icon> \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/mipmap-hdpi/ic_launcher.webp b/src/samples/android/common/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-hdpi/ic_launcher.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/src/samples/android/common/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-hdpi/ic_launcher_round.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-mdpi/ic_launcher.webp b/src/samples/android/common/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-mdpi/ic_launcher.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/src/samples/android/common/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-mdpi/ic_launcher_round.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-xhdpi/ic_launcher.webp b/src/samples/android/common/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-xhdpi/ic_launcher.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/src/samples/android/common/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-xhdpi/ic_launcher_round.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/src/samples/android/common/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-xxhdpi/ic_launcher.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/src/samples/android/common/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/src/samples/android/common/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-xxxhdpi/ic_launcher.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/src/samples/android/common/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 --- /dev/null +++ b/src/samples/android/common/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp Binary files differ
diff --git a/src/samples/android/common/src/main/res/values-night/themes.xml b/src/samples/android/common/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..5410060 --- /dev/null +++ b/src/samples/android/common/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@ +<resources xmlns:tools="http://schemas.android.com/tools"> + <!-- Base application theme. --> + <style name="Theme.Game_activity" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> + <!-- Primary brand color. --> + <item name="colorPrimary">@color/purple_200</item> + <item name="colorPrimaryVariant">@color/purple_700</item> + <item name="colorOnPrimary">@color/black</item> + <!-- Secondary brand color. --> + <item name="colorSecondary">@color/teal_200</item> + <item name="colorSecondaryVariant">@color/teal_200</item> + <item name="colorOnSecondary">@color/black</item> + <!-- Status bar color. --> + <item name="android:statusBarColor">?attr/colorPrimaryVariant</item> + <!-- Customize your theme here. --> + </style> +</resources> \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/values/colors.xml b/src/samples/android/common/src/main/res/values/colors.xml new file mode 100644 index 0000000..09837df --- /dev/null +++ b/src/samples/android/common/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="purple_200">#FFBB86FC</color> + <color name="purple_500">#FF6200EE</color> + <color name="purple_700">#FF3700B3</color> + <color name="teal_200">#FF03DAC5</color> + <color name="teal_700">#FF018786</color> + <color name="black">#FF000000</color> + <color name="white">#FFFFFFFF</color> +</resources> \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/values/strings.xml b/src/samples/android/common/src/main/res/values/strings.xml new file mode 100644 index 0000000..7ea9fa7 --- /dev/null +++ b/src/samples/android/common/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@ +<resources> + <string name="app_name">game_activity</string> +</resources> \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/values/themes.xml b/src/samples/android/common/src/main/res/values/themes.xml new file mode 100644 index 0000000..813c9ec --- /dev/null +++ b/src/samples/android/common/src/main/res/values/themes.xml
@@ -0,0 +1,16 @@ +<resources xmlns:tools="http://schemas.android.com/tools"> + <!-- Base application theme. --> + <style name="Theme.Game_activity" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> + <!-- Primary brand color. --> + <item name="colorPrimary">@color/purple_500</item> + <item name="colorPrimaryVariant">@color/purple_700</item> + <item name="colorOnPrimary">@color/white</item> + <!-- Secondary brand color. --> + <item name="colorSecondary">@color/teal_200</item> + <item name="colorSecondaryVariant">@color/teal_700</item> + <item name="colorOnSecondary">@color/black</item> + <!-- Status bar color. --> + <item name="android:statusBarColor">?attr/colorPrimaryVariant</item> + <!-- Customize your theme here. --> + </style> +</resources> \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/xml/backup_rules.xml b/src/samples/android/common/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000..9b42d90 --- /dev/null +++ b/src/samples/android/common/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + Sample backup rules file; uncomment and customize as necessary. + See https://developer.android.com/guide/topics/data/autobackup + for details. + Note: This file is ignored for devices older that API 31 + See https://developer.android.com/about/versions/12/backup-restore +--> +<full-backup-content> + <!-- + <include domain="sharedpref" path="."/> + <exclude domain="sharedpref" path="device.xml"/> +--> +</full-backup-content> \ No newline at end of file
diff --git a/src/samples/android/common/src/main/res/xml/data_extraction_rules.xml b/src/samples/android/common/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000..be2821f --- /dev/null +++ b/src/samples/android/common/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + Sample data extraction rules file; uncomment and customize as necessary. + See https://developer.android.com/about/versions/12/backup-restore#xml-changes + for details. +--> +<data-extraction-rules> + <cloud-backup> + </cloud-backup> +</data-extraction-rules> \ No newline at end of file
diff --git a/src/samples/android/computeboids/.gitignore b/src/samples/android/computeboids/.gitignore new file mode 100644 index 0000000..98ab34c --- /dev/null +++ b/src/samples/android/computeboids/.gitignore
@@ -0,0 +1,16 @@ +build/ +*.iml +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +/.cxx +local.properties
diff --git a/src/samples/android/computeboids/CMakeLists.txt b/src/samples/android/computeboids/CMakeLists.txt new file mode 100644 index 0000000..24968e1 --- /dev/null +++ b/src/samples/android/computeboids/CMakeLists.txt
@@ -0,0 +1,13 @@ +add_library(computeboids MODULE + src/main/cpp/Compute.cpp + src/main/cpp/Renderer.cc + src/main/cpp/Renderer.h +) + +target_include_directories(chellotriangle PRIVATE SAMPLES_SRC_UTILS_DIR) + +target_link_options(computeboids PUBLIC + "-u Java_com_google_androidgamesdk_GameActivity_initializeNativeCode" +) + +target_link_libraries(computeboids dawn_sample_utils) \ No newline at end of file
diff --git a/src/samples/android/computeboids/build.gradle b/src/samples/android/computeboids/build.gradle new file mode 100644 index 0000000..3e6d315 --- /dev/null +++ b/src/samples/android/computeboids/build.gradle
@@ -0,0 +1,46 @@ +plugins { + id 'com.android.application' +} + +android { + namespace 'com.google.computeboids' + compileSdk 33 + + defaultConfig { + applicationId "com.google.computeboids" + minSdk 30 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + debuggable true + jniDebuggable true + } + debug { + debuggable true + jniDebuggable true + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation project(':common') + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.games:games-activity:1.2.2' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +}
diff --git a/src/samples/android/computeboids/proguard-rules.pro b/src/samples/android/computeboids/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/src/samples/android/computeboids/proguard-rules.pro
@@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file
diff --git a/src/samples/android/computeboids/src/main/AndroidManifest.xml b/src/samples/android/computeboids/src/main/AndroidManifest.xml new file mode 100644 index 0000000..15320d6 --- /dev/null +++ b/src/samples/android/computeboids/src/main/AndroidManifest.xml
@@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> + + <application + android:allowBackup="true" + android:dataExtractionRules="@xml/data_extraction_rules" + android:fullBackupContent="@xml/backup_rules" + android:icon="@mipmap/ic_launcher" + android:label="computeboids" + android:roundIcon="@drawable/ic_launcher_background" + android:supportsRtl="true" + android:theme="@style/Theme.Game_activity" + tools:targetApi="31"> + <activity + android:name=".MainActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + + <meta-data + android:name="android.app.lib_name" + android:value="computeboids" /> + </activity> + </application> + +</manifest> \ No newline at end of file
diff --git a/src/samples/android/computeboids/src/main/cpp/Compute.cpp b/src/samples/android/computeboids/src/main/cpp/Compute.cpp new file mode 100644 index 0000000..944bec2 --- /dev/null +++ b/src/samples/android/computeboids/src/main/cpp/Compute.cpp
@@ -0,0 +1,57 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include <game-activity/GameActivity.cpp> +#include "Renderer.h" // NOLINT + +extern "C" { +#include <game-activity/native_app_glue/android_native_app_glue.c> + +void handle_cmd(android_app* pApp, int32_t cmd) { + switch (cmd) { + case APP_CMD_INIT_WINDOW: + // A new window is created, associate a renderer with it. + pApp->userData = new Renderer(pApp); + break; + case APP_CMD_TERM_WINDOW: + // The window is being destroyed. Use this to clean up your userData to avoid leaking + // resources. + if (pApp->userData) { + auto* pRenderer = reinterpret_cast<Renderer*>(pApp->userData); + pApp->userData = nullptr; + delete pRenderer; + } + break; + default: + break; + } +} + +void android_main(android_app* pApp) { + pApp->onAppCmd = handle_cmd; + int events; + android_poll_source* pSource; + + do { + if (ALooper_pollAll(0, nullptr, &events, reinterpret_cast<void**>(&pSource)) >= 0) { + if (pSource) { + pSource->process(pApp, pSource); + } + } + if (pApp->userData) { + auto* pRenderer = reinterpret_cast<Renderer*>(pApp->userData); + pRenderer->GameLoop(); + } + } while (!pApp->destroyRequested); +} +}
diff --git a/src/samples/android/computeboids/src/main/cpp/Renderer.cc b/src/samples/android/computeboids/src/main/cpp/Renderer.cc new file mode 100644 index 0000000..4cd48da --- /dev/null +++ b/src/samples/android/computeboids/src/main/cpp/Renderer.cc
@@ -0,0 +1,282 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include "Renderer.h" // NOLINT +#include "dawn/common/Log.h" +#include "dawn/utils/ComboRenderPipelineDescriptor.h" +#include "dawn/utils/SystemUtils.h" +#include "dawn/utils/WGPUHelpers.h" + +void Renderer::InitBuffers() { + std::array<std::array<float, 2>, 3> model = {{ + {-0.01, -0.02}, + {0.01, -0.02}, + {0.00, 0.02}, + }}; + modelBuffer = + dawn::utils::CreateBufferFromData(device, &model, sizeof(model), wgpu::BufferUsage::Vertex); + + Renderer::SimParams params = {0.04f, 0.1f, 0.025f, 0.025f, 0.02f, 0.05f, 0.005f, kNumParticles}; + updateParams = dawn::utils::CreateBufferFromData(device, ¶ms, sizeof(params), + wgpu::BufferUsage::Uniform); + + std::vector<Particle> initialParticles(kNumParticles); + { + std::mt19937 generator; + std::uniform_real_distribution<float> dist(-1.0f, 1.0f); + for (auto& p : initialParticles) { + p.pos = {dist(generator), dist(generator)}; + p.vel = {dist(generator) * 0.1f, dist(generator) * 0.1f}; + } + } + + for (size_t i = 0; i < 2; i++) { + wgpu::BufferDescriptor descriptor; + descriptor.size = sizeof(Particle) * kNumParticles; + descriptor.usage = + wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::Vertex | wgpu::BufferUsage::Storage; + particleBuffers[i] = device.CreateBuffer(&descriptor); + + queue.WriteBuffer(particleBuffers[i], 0, + reinterpret_cast<uint8_t*>(initialParticles.data()), + sizeof(Particle) * kNumParticles); + } +} + +void Renderer::InitRender() { + wgpu::ShaderModule vsModule = dawn::utils::CreateShaderModule(device, R"( + struct VertexIn { + @location(0) a_particlePos : vec2f, + @location(1) a_particleVel : vec2f, + @location(2) a_pos : vec2f, + }; + + @vertex + fn main(input : VertexIn) -> @builtin(position) vec4f { + var angle : f32 = -atan2(input.a_particleVel.x, input.a_particleVel.y); + var pos : vec2f = vec2f( + (input.a_pos.x * cos(angle)) - (input.a_pos.y * sin(angle)), + (input.a_pos.x * sin(angle)) + (input.a_pos.y * cos(angle))); + return vec4f(pos + input.a_particlePos, 0.0, 1.0); + } + )"); + + wgpu::ShaderModule fsModule = dawn::utils::CreateShaderModule(device, R"( + @fragment + fn main() -> @location(0) vec4f { + return vec4f(1.0, 1.0, 1.0, 1.0); + } + )"); + + depthStencilView = CreateDefaultDepthStencilView(device); + + dawn::utils::ComboRenderPipelineDescriptor descriptor; + + descriptor.vertex.module = vsModule; + descriptor.vertex.bufferCount = 2; + descriptor.cBuffers[0].arrayStride = sizeof(Particle); + descriptor.cBuffers[0].stepMode = wgpu::VertexStepMode::Instance; + descriptor.cBuffers[0].attributeCount = 2; + descriptor.cAttributes[0].offset = offsetof(Particle, pos); + descriptor.cAttributes[0].format = wgpu::VertexFormat::Float32x2; + descriptor.cAttributes[1].shaderLocation = 1; + descriptor.cAttributes[1].offset = offsetof(Particle, vel); + descriptor.cAttributes[1].format = wgpu::VertexFormat::Float32x2; + descriptor.cBuffers[1].arrayStride = 2 * sizeof(float); + descriptor.cBuffers[1].attributeCount = 1; + descriptor.cBuffers[1].attributes = &descriptor.cAttributes[2]; + descriptor.cAttributes[2].shaderLocation = 2; + descriptor.cAttributes[2].format = wgpu::VertexFormat::Float32x2; + + descriptor.cFragment.module = fsModule; + descriptor.EnableDepthStencil(wgpu::TextureFormat::Depth24PlusStencil8); + descriptor.cTargets[0].format = GetPreferredSwapChainTextureFormat(); + + renderPipeline = device.CreateRenderPipeline(&descriptor); +} + +void Renderer::InitSim() { + wgpu::ShaderModule module = dawn::utils::CreateShaderModule(device, R"( + struct Particle { + pos : vec2f, + vel : vec2f, + }; + struct SimParams { + deltaT : f32, + rule1Distance : f32, + rule2Distance : f32, + rule3Distance : f32, + rule1Scale : f32, + rule2Scale : f32, + rule3Scale : f32, + particleCount : u32, + }; + struct Particles { + particles : array<Particle>, + }; + @binding(0) @group(0) var<uniform> params : SimParams; + @binding(1) @group(0) var<storage, read_write> particlesA : Particles; + @binding(2) @group(0) var<storage, read_write> particlesB : Particles; + + // https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp + @compute @workgroup_size(64) + fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3u) { + var index : u32 = GlobalInvocationID.x; + if (index >= params.particleCount) { + return; + } + var vPos : vec2f = particlesA.particles[index].pos; + var vVel : vec2f = particlesA.particles[index].vel; + var cMass : vec2f = vec2f(0.0, 0.0); + var cVel : vec2f = vec2f(0.0, 0.0); + var colVel : vec2f = vec2f(0.0, 0.0); + var cMassCount : u32 = 0u; + var cVelCount : u32 = 0u; + var pos : vec2f; + var vel : vec2f; + + for (var i : u32 = 0u; i < params.particleCount; i = i + 1u) { + if (i == index) { + continue; + } + + pos = particlesA.particles[i].pos.xy; + vel = particlesA.particles[i].vel.xy; + if (distance(pos, vPos) < params.rule1Distance) { + cMass = cMass + pos; + cMassCount = cMassCount + 1u; + } + if (distance(pos, vPos) < params.rule2Distance) { + colVel = colVel - (pos - vPos); + } + if (distance(pos, vPos) < params.rule3Distance) { + cVel = cVel + vel; + cVelCount = cVelCount + 1u; + } + } + + if (cMassCount > 0u) { + cMass = (cMass / vec2f(f32(cMassCount), f32(cMassCount))) - vPos; + } + + if (cVelCount > 0u) { + cVel = cVel / vec2f(f32(cVelCount), f32(cVelCount)); + } + vVel = vVel + (cMass * params.rule1Scale) + (colVel * params.rule2Scale) + + (cVel * params.rule3Scale); + + // clamp velocity for a more pleasing simulation + vVel = normalize(vVel) * clamp(length(vVel), 0.0, 0.1); + // kinematic update + vPos = vPos + (vVel * params.deltaT); + + // Wrap around boundary + if (vPos.x < -1.0) { + vPos.x = 1.0; + } + if (vPos.x > 1.0) { + vPos.x = -1.0; + } + if (vPos.y < -1.0) { + vPos.y = 1.0; + } + if (vPos.y > 1.0) { + vPos.y = -1.0; + } + + // Write back + particlesB.particles[index].pos = vPos; + particlesB.particles[index].vel = vVel; + return; + } + )"); + + auto bgl = dawn::utils::MakeBindGroupLayout( + device, { + {0, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Uniform}, + {1, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}, + {2, wgpu::ShaderStage::Compute, wgpu::BufferBindingType::Storage}, + }); + + wgpu::PipelineLayout pl = dawn::utils::MakeBasicPipelineLayout(device, &bgl); + + wgpu::ComputePipelineDescriptor csDesc; + csDesc.layout = pl; + csDesc.compute.module = module; + csDesc.compute.entryPoint = "main"; + updatePipeline = device.CreateComputePipeline(&csDesc); + + for (uint32_t i = 0; i < 2; ++i) { + updateBGs[i] = dawn::utils::MakeBindGroup( + device, bgl, + { + {0, updateParams, 0, sizeof(SimParams)}, + {1, particleBuffers[i], 0, kNumParticles * sizeof(Particle)}, + {2, particleBuffers[(i + 1) % 2], 0, kNumParticles * sizeof(Particle)}, + }); + } +} + +wgpu::CommandBuffer Renderer::createCommandBuffer(const wgpu::TextureView backbufferView, + size_t i) { + auto& bufferDst = particleBuffers[(i + 1) % 2]; + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); + + { + wgpu::ComputePassEncoder pass = encoder.BeginComputePass(); + pass.SetPipeline(updatePipeline); + pass.SetBindGroup(0, updateBGs[i]); + pass.DispatchWorkgroups(kNumParticles / 64); + pass.End(); + } + + { + dawn::utils::ComboRenderPassDescriptor renderPass({backbufferView}, depthStencilView); + wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass); + pass.SetPipeline(renderPipeline); + pass.SetVertexBuffer(0, bufferDst); + pass.SetVertexBuffer(1, modelBuffer); + pass.Draw(3, kNumParticles); + pass.End(); + } + + return encoder.Finish(); +} + +void Renderer::Init() { + device = CreateCppDawnDeviceForAndroid(androidDesc); + queue = device.GetQueue(); + swapchain = GetSwapChain(); + + InitBuffers(); + InitRender(); + InitSim(); +} + +void Renderer::Frame() { + wgpu::TextureView backbufferView = swapchain.GetCurrentTextureView(); + + wgpu::CommandBuffer commandBuffer = createCommandBuffer(backbufferView, pingpong); + queue.Submit(1, &commandBuffer); + swapchain.Present(); + + pingpong = (pingpong + 1) % 2; +} + +void Renderer::GameLoop() { + if (!deviceInitialised) { + Init(); + deviceInitialised = true; + } + Frame(); +}
diff --git a/src/samples/android/computeboids/src/main/cpp/Renderer.h b/src/samples/android/computeboids/src/main/cpp/Renderer.h new file mode 100644 index 0000000..c1a99c1 --- /dev/null +++ b/src/samples/android/computeboids/src/main/cpp/Renderer.h
@@ -0,0 +1,85 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include <game-activity/native_app_glue/android_native_app_glue.h> +#include <array> +#include <cstring> +#include <random> +#include <vector> + +#include "../../../../../utils/SampleUtils.h" + +#include "dawn/utils/ComboRenderPipelineDescriptor.h" +#include "dawn/utils/SystemUtils.h" +#include "dawn/utils/WGPUHelpers.h" + +#ifndef APP_SRC_MAIN_CPP_RENDERER_H_ +#define APP_SRC_MAIN_CPP_RENDERER_H_ + +class Renderer { + public: + wgpu::Device device; + wgpu::SwapChain swapchain; + wgpu::RenderPipeline pipeline; + wgpu::Queue queue; + wgpu::SurfaceDescriptorFromAndroidNativeWindow androidDesc; + wgpu::Instance instance; + wgpu::InstanceDescriptor desc; + bool deviceInitialised; + + wgpu::TextureView depthStencilView; + + wgpu::Buffer modelBuffer; + std::array<wgpu::Buffer, 2> particleBuffers; + + wgpu::RenderPipeline renderPipeline; + + wgpu::Buffer updateParams; + wgpu::ComputePipeline updatePipeline; + std::array<wgpu::BindGroup, 2> updateBGs; + + size_t pingpong = 0; + + static const uint32_t kNumParticles = 1024; + + struct Particle { + std::array<float, 2> pos; + std::array<float, 2> vel; + }; + + struct SimParams { + float deltaT; + float rule1Distance; + float rule2Distance; + float rule3Distance; + float rule1Scale; + float rule2Scale; + float rule3Scale; + int particleCount; + }; + + explicit Renderer(android_app* app) { + deviceInitialised = false; + androidDesc.window = app->window; + androidDesc.sType = wgpu::SType::SurfaceDescriptorFromAndroidNativeWindow; + } + void Init(); + void InitBuffers(); + void InitRender(); + void InitSim(); + wgpu::CommandBuffer createCommandBuffer(const wgpu::TextureView backbufferView, size_t i); + void Frame(); + void GameLoop(); +}; + +#endif // APP_SRC_MAIN_CPP_RENDERER_H_
diff --git a/src/samples/android/computeboids/src/main/java/com/google/computeboids/MainActivity.java b/src/samples/android/computeboids/src/main/java/com/google/computeboids/MainActivity.java new file mode 100644 index 0000000..feda135 --- /dev/null +++ b/src/samples/android/computeboids/src/main/java/com/google/computeboids/MainActivity.java
@@ -0,0 +1,27 @@ +package com.google.computeboids; + +import android.view.View; +import com.google.androidgamesdk.GameActivity; + +public class MainActivity extends GameActivity { + static { + System.loadLibrary("computeboids"); + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + + if (hasFocus) { + hideSystemUi(); + } + } + + private void hideSystemUi() { + View decorView = getWindow().getDecorView(); + decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN); + } +}
diff --git a/src/samples/android/cpphellotriangle/.gitignore b/src/samples/android/cpphellotriangle/.gitignore new file mode 100644 index 0000000..3b1e1cd --- /dev/null +++ b/src/samples/android/cpphellotriangle/.gitignore
@@ -0,0 +1,15 @@ +*.iml +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties +build/
diff --git a/src/samples/android/cpphellotriangle/CMakeLists.txt b/src/samples/android/cpphellotriangle/CMakeLists.txt new file mode 100644 index 0000000..ff002cf --- /dev/null +++ b/src/samples/android/cpphellotriangle/CMakeLists.txt
@@ -0,0 +1,13 @@ +add_library(cpphellotriangle MODULE + src/main/cpp/CppHelloTriangle.cpp + src/main/cpp/Renderer.cc + src/main/cpp/Renderer.h +) + +target_include_directories(chellotriangle PRIVATE SAMPLES_SRC_UTILS_DIR) + +target_link_options(cpphellotriangle PUBLIC + "-u Java_com_google_androidgamesdk_GameActivity_initializeNativeCode" +) + +target_link_libraries(cpphellotriangle dawn_sample_utils) \ No newline at end of file
diff --git a/src/samples/android/cpphellotriangle/build.gradle b/src/samples/android/cpphellotriangle/build.gradle new file mode 100644 index 0000000..7a3b463 --- /dev/null +++ b/src/samples/android/cpphellotriangle/build.gradle
@@ -0,0 +1,47 @@ +plugins { + id 'com.android.application' +} + +android { + namespace 'com.google.cpphellotriangle' + compileSdk 33 + + defaultConfig { + applicationId "com.google.cpphellotriangle" + minSdk 30 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + debuggable true + jniDebuggable true + } + debug { + debuggable true + jniDebuggable true + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation project(':common') + implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.games:games-activity:1.2.2' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +}
diff --git a/src/samples/android/cpphellotriangle/src/main/AndroidManifest.xml b/src/samples/android/cpphellotriangle/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9483d7d --- /dev/null +++ b/src/samples/android/cpphellotriangle/src/main/AndroidManifest.xml
@@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools"> + + <application + android:allowBackup="true" + android:dataExtractionRules="@xml/data_extraction_rules" + android:fullBackupContent="@xml/backup_rules" + android:icon="@mipmap/ic_launcher" + android:label="cpphellotriangle" + android:roundIcon="@drawable/ic_launcher_background" + android:supportsRtl="true" + android:theme="@style/Theme.Game_activity" + tools:targetApi="31"> + <activity + android:name=".MainActivity" + android:exported="true"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + + <meta-data + android:name="android.app.lib_name" + android:value="cpphellotriangle" /> + </activity> + </application> + +</manifest> \ No newline at end of file
diff --git a/src/samples/android/cpphellotriangle/src/main/cpp/CppHelloTriangle.cpp b/src/samples/android/cpphellotriangle/src/main/cpp/CppHelloTriangle.cpp new file mode 100644 index 0000000..d2c0459 --- /dev/null +++ b/src/samples/android/cpphellotriangle/src/main/cpp/CppHelloTriangle.cpp
@@ -0,0 +1,57 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include <game-activity/GameActivity.cpp> +#include "Renderer.h" // NOLINT + +extern "C" { +#include <game-activity/native_app_glue/android_native_app_glue.c> // NOLINT + +void handle_cmd(android_app* pApp, int32_t cmd) { + switch (cmd) { + case APP_CMD_INIT_WINDOW: + // A new window is created, associate a renderer with it. + pApp->userData = new Renderer(pApp); + break; + case APP_CMD_TERM_WINDOW: + // The window is being destroyed. Use this to clean up your userData to avoid leaking + // resources. + if (pApp->userData) { + auto* pRenderer = reinterpret_cast<Renderer*>(pApp->userData); + pApp->userData = nullptr; + delete pRenderer; + } + break; + default: + break; + } +} + +void android_main(android_app* pApp) { + pApp->onAppCmd = handle_cmd; + int events; + android_poll_source* pSource; + + do { + if (ALooper_pollAll(0, nullptr, &events, reinterpret_cast<void**>(&pSource)) >= 0) { + if (pSource) { + pSource->process(pApp, pSource); + } + } + if (pApp->userData) { + auto* pRenderer = reinterpret_cast<Renderer*>(pApp->userData); + pRenderer->GameLoop(); + } + } while (!pApp->destroyRequested); +} +}
diff --git a/src/samples/android/cpphellotriangle/src/main/cpp/Renderer.cc b/src/samples/android/cpphellotriangle/src/main/cpp/Renderer.cc new file mode 100644 index 0000000..a14505e --- /dev/null +++ b/src/samples/android/cpphellotriangle/src/main/cpp/Renderer.cc
@@ -0,0 +1,90 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include "Renderer.h" // NOLINT +#include "dawn/common/Log.h" + +void Renderer::Init() { + device = CreateCppDawnDeviceForAndroid(androidDesc); + queue = device.GetQueue(); + swapChain = GetSwapChain(); + const char shaderSource[] = R"( + @vertex fn vertexMain(@builtin(vertex_index) i : u32) -> + @builtin(position) vec4f { + const pos = array(vec2f(-0.5, -0.5), vec2f(0.5, -0.5), vec2f(0.0, 0.5)); + return vec4f(pos[i], 0, 1); + } + @fragment fn fragmentMain() -> @location(0) vec4f { + return vec4f(0.0, 0.4, 1.0, 1.0); + } + )"; + + wgpu::ShaderModuleWGSLDescriptor shaderCodeDesc; + shaderCodeDesc.code = shaderSource; + wgpu::ShaderModuleDescriptor shaderDesc; + shaderDesc.nextInChain = &shaderCodeDesc; + wgpu::ShaderModule shaderModule = device.CreateShaderModule(&shaderDesc); + wgpu::RenderPipelineDescriptor pipelineDesc; + + // Vertex shader + pipelineDesc.vertex.module = shaderModule; + pipelineDesc.primitive.topology = wgpu::PrimitiveTopology::TriangleList; + + // Fragment shader + wgpu::FragmentState fragmentState; + pipelineDesc.fragment = &fragmentState; + fragmentState.module = shaderModule; + + + wgpu::ColorTargetState colorTarget; + colorTarget.format = GetPreferredSwapChainTextureFormat(); + + fragmentState.targetCount = 1; + fragmentState.targets = &colorTarget; + pipeline = device.CreateRenderPipeline(&pipelineDesc); +} + +void Renderer::Frame() { + wgpu::TextureView nextTexture = swapChain.GetCurrentTextureView(); + wgpu::RenderPassColorAttachment renderPassColorAttachment; + renderPassColorAttachment.view = nextTexture; + renderPassColorAttachment.loadOp = wgpu::LoadOp::Clear; + renderPassColorAttachment.storeOp = wgpu::StoreOp::Store; + renderPassColorAttachment.clearValue = wgpu::Color{0.9, 0.1, 0.2, 1.0}; + + wgpu::RenderPassDescriptor renderPassDesc; + renderPassDesc.colorAttachmentCount = 1; + renderPassDesc.colorAttachments = &renderPassColorAttachment; + + wgpu::CommandEncoderDescriptor commandEncoderDesc; + commandEncoderDesc.label = "Command Encoder"; + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(&commandEncoderDesc); + wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDesc); + + renderPass.SetPipeline(pipeline); + renderPass.Draw(3); + renderPass.End(); + + wgpu::CommandBuffer commands = encoder.Finish(); + + device.GetQueue().Submit(1, &commands); + swapChain.Present(); +} + +void Renderer::GameLoop() { + if (!deviceInitialised) { + Init(); + deviceInitialised = true; + } + Frame(); +}
diff --git a/src/samples/android/cpphellotriangle/src/main/cpp/Renderer.h b/src/samples/android/cpphellotriangle/src/main/cpp/Renderer.h new file mode 100644 index 0000000..a9fe1ce --- /dev/null +++ b/src/samples/android/cpphellotriangle/src/main/cpp/Renderer.h
@@ -0,0 +1,41 @@ +// Copyright 2023 The Dawn Authors +// +// 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. +#include <game-activity/native_app_glue/android_native_app_glue.h> +#include "../../../../../utils/SampleUtils.h" + +#ifndef APP_SRC_MAIN_CPP_RENDERER_H_ +#define APP_SRC_MAIN_CPP_RENDERER_H_ + +class Renderer { + public: + wgpu::Device device; + wgpu::SwapChain swapChain; + wgpu::RenderPipeline pipeline; + wgpu::Queue queue; + wgpu::SurfaceDescriptorFromAndroidNativeWindow androidDesc; + wgpu::Instance instance; + wgpu::InstanceDescriptor desc; + bool deviceInitialised; + + explicit Renderer(android_app* app) { + deviceInitialised = false; + androidDesc.window = app->window; + androidDesc.sType = wgpu::SType::SurfaceDescriptorFromAndroidNativeWindow; + } + void Init(); + void Frame(); + void GameLoop(); +}; + +#endif // APP_SRC_MAIN_CPP_RENDERER_H_
diff --git a/src/samples/android/cpphellotriangle/src/main/java/com/google/cpphellotriangle/MainActivity.java b/src/samples/android/cpphellotriangle/src/main/java/com/google/cpphellotriangle/MainActivity.java new file mode 100644 index 0000000..207cfb4 --- /dev/null +++ b/src/samples/android/cpphellotriangle/src/main/java/com/google/cpphellotriangle/MainActivity.java
@@ -0,0 +1,28 @@ +package com.google.cpphellotriangle; + +import android.view.View; + +import com.google.androidgamesdk.GameActivity; + +public class MainActivity extends GameActivity { + static { + System.loadLibrary("cpphellotriangle"); + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + + if (hasFocus) { + hideSystemUi(); + } + } + + private void hideSystemUi() { + View decorView = getWindow().getDecorView(); + decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN); + } +}
diff --git a/src/samples/android/gradle.properties b/src/samples/android/gradle.properties new file mode 100644 index 0000000..3e927b1 --- /dev/null +++ b/src/samples/android/gradle.properties
@@ -0,0 +1,21 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file
diff --git a/src/samples/android/gradle/wrapper/gradle-wrapper.jar b/src/samples/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c --- /dev/null +++ b/src/samples/android/gradle/wrapper/gradle-wrapper.jar Binary files differ
diff --git a/src/samples/android/gradle/wrapper/gradle-wrapper.properties b/src/samples/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..10d1673 --- /dev/null +++ b/src/samples/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@ +#Tue Sep 12 13:16:48 UTC 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists
diff --git a/src/samples/android/gradlew b/src/samples/android/gradlew new file mode 100755 index 0000000..4f906e0 --- /dev/null +++ b/src/samples/android/gradlew
@@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# 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 +# +# https://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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@"
diff --git a/src/samples/android/gradlew.bat b/src/samples/android/gradlew.bat new file mode 100644 index 0000000..ac1b06f --- /dev/null +++ b/src/samples/android/gradlew.bat
@@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega
diff --git a/src/samples/android/settings.gradle b/src/samples/android/settings.gradle new file mode 100644 index 0000000..c17a106 --- /dev/null +++ b/src/samples/android/settings.gradle
@@ -0,0 +1,21 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} +rootProject.name = "android-samples" +include ':chellotriangle' +include ':cpphellotriangle' +include ':common' +include ':computeboids' +project(':common').projectDir = new File(settingsDir, 'common') +
diff --git a/src/samples/utils/CMakeLists.txt b/src/samples/utils/CMakeLists.txt new file mode 100644 index 0000000..6cbe6de --- /dev/null +++ b/src/samples/utils/CMakeLists.txt
@@ -0,0 +1,65 @@ +# Copyright 2020 The Dawn & Tint Authors +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# 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. + +add_library(dawn_sample_utils STATIC ${SAMPLES_PLACEHOLDER_FILE}) +target_include_directories(dawn_sample_utils INTERFACE + "${SAMPLES_SRC_DIR}" +) + +common_compile_options(dawn_sample_utils) +target_sources(dawn_sample_utils PRIVATE + "SampleUtils.cpp" + "SampleUtils.h" +) + +target_link_libraries(dawn_sample_utils PUBLIC + dawn_internal_config + dawncpp + dawn_proc + dawn_common + dawn_native + dawn_wire + dawn_utils +) + +if (DAWN_BUILD_ANDROID_SAMPLES) + target_compile_definitions(dawn_sample_utils PRIVATE "DAWN_ENABLE_BACKEND_ANDROID") + set(SAMPLES_SRC_UTILS_DIR "${SAMPLES_SRC_DIR}/samples/utils") + find_package(game-activity REQUIRED CONFIG) + + target_link_libraries(dawn_sample_utils PUBLIC + jnigraphics + android + log + game-activity::game-activity_static + ) +else() + target_link_libraries(dawn_sample_utils PUBLIC + dawn_glfw + glfw + ) +endif() \ No newline at end of file
diff --git a/src/samples/SampleUtils.cpp b/src/samples/utils/SampleUtils.cpp similarity index 89% rename from src/samples/SampleUtils.cpp rename to src/samples/utils/SampleUtils.cpp index 2def23b..d494307 100644 --- a/src/samples/SampleUtils.cpp +++ b/src/samples/utils/SampleUtils.cpp
@@ -1,32 +1,19 @@ -// Copyright 2017 The Dawn & Tint Authors +// Copyright 2017 The Dawn Authors // -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: +// 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 // -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. +// http://www.apache.org/licenses/LICENSE-2.0 // -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// 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. +// 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. #include "SampleUtils.h" - +#include <dawn/webgpu.h> #include <algorithm> #include <cstring> #include <memory> @@ -34,7 +21,6 @@ #include <string_view> #include <vector> -#include "GLFW/glfw3.h" #include "dawn/common/Assert.h" #include "dawn/common/Log.h" #include "dawn/common/Platform.h" @@ -44,7 +30,11 @@ #include "dawn/utils/TerribleCommandBuffer.h" #include "dawn/wire/WireClient.h" #include "dawn/wire/WireServer.h" + +#if !defined(DAWN_ENABLE_BACKEND_ANDROID) +#include "GLFW/glfw3.h" #include "webgpu/webgpu_glfw.h" +#endif void PrintDeviceError(WGPUErrorType errorType, const char* message, void*) { const char* errorTypeName = ""; @@ -88,14 +78,14 @@ // Default to D3D12, Metal, Vulkan, OpenGL in that order as D3D12 and Metal are the preferred on // their respective platforms, and Vulkan is preferred to OpenGL -#if defined(DAWN_ENABLE_BACKEND_D3D12) +#if defined(DAWN_ENABLE_BACKEND_VULKAN) || defined(DAWN_ENABLE_BACKEND_ANDROID) +static wgpu::BackendType backendType = wgpu::BackendType::Vulkan; +#elif defined(DAWN_ENABLE_BACKEND_D3D12) static wgpu::BackendType backendType = wgpu::BackendType::D3D12; #elif defined(DAWN_ENABLE_BACKEND_D3D11) static wgpu::BackendType backendType = wgpu::BackendType::D3D11; #elif defined(DAWN_ENABLE_BACKEND_METAL) static wgpu::BackendType backendType = wgpu::BackendType::Metal; -#elif defined(DAWN_ENABLE_BACKEND_VULKAN) -static wgpu::BackendType backendType = wgpu::BackendType::Vulkan; #elif defined(DAWN_ENABLE_BACKEND_OPENGLES) static wgpu::BackendType backendType = wgpu::BackendType::OpenGLES; #elif defined(DAWN_ENABLE_BACKEND_DESKTOP_GL) @@ -114,7 +104,6 @@ static wgpu::SwapChain swapChain; static GLFWwindow* window = nullptr; - static dawn::wire::WireServer* wireServer = nullptr; static dawn::wire::WireClient* wireClient = nullptr; static dawn::utils::TerribleCommandBuffer* c2sBuf = nullptr; @@ -123,7 +112,17 @@ static constexpr uint32_t kWidth = 640; static constexpr uint32_t kHeight = 480; +#if defined(DAWN_ENABLE_BACKEND_ANDROID) +static wgpu::SurfaceDescriptorFromAndroidNativeWindow androidDesc; + +wgpu::Device CreateCppDawnDeviceForAndroid(wgpu::SurfaceDescriptorFromAndroidNativeWindow desc) { + androidDesc = desc; + return CreateCppDawnDevice(); +} +#endif + wgpu::Device CreateCppDawnDevice() { +#if !defined(DAWN_ENABLE_BACKEND_ANDROID) dawn::ScopedEnvironmentVar angleDefaultPlatform; if (dawn::GetEnvironmentVar("ANGLE_DEFAULT_PLATFORM").first.empty()) { angleDefaultPlatform.Set("ANGLE_DEFAULT_PLATFORM", "swiftshader"); @@ -142,6 +141,8 @@ return wgpu::Device(); } +#endif + WGPUInstanceDescriptor instanceDescriptor{}; instanceDescriptor.features.timedWaitAnyEnable = true; instance = std::make_unique<dawn::native::Instance>(&instanceDescriptor); @@ -193,10 +194,16 @@ DawnProcTable backendProcs = dawn::native::GetProcs(); // Create the swapchain +#if defined(DAWN_ENABLE_BACKEND_ANDROID) + WGPUSurfaceDescriptor surfaceDesc = {}; + surfaceDesc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&androidDesc); + WGPUSurface surface = backendProcs.instanceCreateSurface(instance->Get(), &surfaceDesc); +#else auto surfaceChainedDesc = wgpu::glfw::SetupWindowAndGetSurfaceDescriptor(window); WGPUSurfaceDescriptor surfaceDesc; surfaceDesc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(surfaceChainedDesc.get()); WGPUSurface surface = backendProcs.instanceCreateSurface(instance->Get(), &surfaceDesc); +#endif WGPUSwapChainDescriptor swapChainDesc = {}; swapChainDesc.usage = WGPUTextureUsage_RenderAttachment; @@ -256,7 +263,33 @@ return wgpu::Device::Acquire(cDevice); } +#if !defined(DAWN_ENABLE_BACKEND_ANDROID) +void DoFlush() { + if (cmdBufType == CmdBufType::Terrible) { + bool c2sSuccess = c2sBuf->Flush(); + bool s2cSuccess = s2cBuf->Flush(); + + DAWN_ASSERT(c2sSuccess && s2cSuccess); + } + glfwPollEvents(); +} + +bool ShouldQuit() { + return glfwWindowShouldClose(window); +} + +GLFWwindow* GetGLFWWindow() { + return window; +} + +#endif + wgpu::TextureFormat GetPreferredSwapChainTextureFormat() { +// Currently, dawn accepts only RGBA8Unorm for Android. +#if defined(DAWN_ENABLE_BACKEND_ANDROID) + return wgpu::TextureFormat::RGBA8Unorm; +#endif + // TODO(dawn:1362): Return the adapter's preferred format when implemented. return wgpu::TextureFormat::BGRA8Unorm; } @@ -420,24 +453,6 @@ return true; } -void DoFlush() { - if (cmdBufType == CmdBufType::Terrible) { - bool c2sSuccess = c2sBuf->Flush(); - bool s2cSuccess = s2cBuf->Flush(); - - DAWN_ASSERT(c2sSuccess && s2cSuccess); - } - glfwPollEvents(); -} - -bool ShouldQuit() { - return glfwWindowShouldClose(window); -} - -GLFWwindow* GetGLFWWindow() { - return window; -} - void ProcessEvents() { dawn::native::InstanceProcessEvents(instance->Get()); }
diff --git a/src/samples/utils/SampleUtils.h b/src/samples/utils/SampleUtils.h new file mode 100644 index 0000000..1281578 --- /dev/null +++ b/src/samples/utils/SampleUtils.h
@@ -0,0 +1,35 @@ +// Copyright 2017 The Dawn Authors +// +// 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 SRC_DAWN_SAMPLES_SAMPLEUTILS_H_ +#define SRC_DAWN_SAMPLES_SAMPLEUTILS_H_ + +#include "dawn/webgpu_cpp.h" + +bool InitSample(int argc, const char** argv); +void DoFlush(); +bool ShouldQuit(); + +struct GLFWwindow; +struct GLFWwindow* GetGLFWWindow(); + +wgpu::Device CreateCppDawnDeviceForAndroid( + wgpu::SurfaceDescriptorFromAndroidNativeWindow androidDesc); +wgpu::Device CreateCppDawnDevice(); +wgpu::TextureFormat GetPreferredSwapChainTextureFormat(); +wgpu::SwapChain GetSwapChain(); +wgpu::TextureView CreateDefaultDepthStencilView(const wgpu::Device& device); +void ProcessEvents(); + +#endif // SRC_DAWN_SAMPLES_SAMPLEUTILS_H_
diff --git a/third_party/glfw b/third_party/glfw index 62e175e..7b15201 160000 --- a/third_party/glfw +++ b/third_party/glfw
@@ -1 +1 @@ -Subproject commit 62e175ef9fae75335575964c845a302447c012c7 +Subproject commit 7b152019dab027dfd276e37cacaacd439075f6c3