Jetpack WebGPU'yu kullanmak için projenizin aşağıdaki minimum koşulları karşılaması gerekir:
- Minimum API düzeyi: Android API 24 (Nougat) veya sonraki sürümler gereklidir.
- Donanım: Arka uç için Vulkan 1.1 veya sonraki sürümleri destekleyen cihazlar tercih edilir.
- Uyumluluk modu ve OpenGL ES desteği:
GPUAdapteristenirken standartlaştırılmışfeatureLevelseçeneğicompatibilityolarak ayarlanarak WebGPU'nun uyumluluk modu ile kullanılması mümkündür.
// Example of requesting an adapter with "compatibility" mode enabled:
val adapter = instance.requestAdapter(
GPURequestAdapterOptions(featureLevel = FeatureLevel.Compatibility))
Yükleme ve kurulum
Ön koşullar:
Android Studio: Android Studio'nun en son sürümünü resmi web sitesinden indirin ve Android Studio Yükleme Kılavuzu'ndaki talimatları uygulayın.
Yeni proje oluşturma
Android Studio yüklendikten sonra WebGPU projenizi ayarlamak için aşağıdaki adımları uygulayın:
- Yeni bir proje başlatma: Android Studio'yu açın ve Yeni Proje'yi tıklayın.
Şablon seçin: Android Studio'da Boş Etkinlik şablonunu seçip İleri'yi tıklayın.
Şekil 1. Android Studio'da yeni bir proje oluşturma Projenizi yapılandırın:
- Ad: Projenize bir ad verin (ör. "JetpackWebGPUSample").
- Paket Adı: Paket adının, seçtiğiniz ad alanıyla (ör. com.example.webgpuapp) eşleştiğini doğrulayın.
- Dil: Kotlin'i seçin.
- Minimum SDK: Bu kitaplık için önerilen API 24: Android 7.0 (Nougat) veya sonraki bir sürümü seçin.
- Build Configuration Language: Modern bağımlılık yönetimi için Kotlin DSL (build.gradle.kts) kullanılması önerilir.
Şekil 2. Boş bir etkinlikle başlama Bitir: Bitir'i tıklayın ve Android Studio'nun proje dosyalarınızı senkronize etmesini bekleyin.
WebGPU Jetpack kitaplığını ekleme
- Uygulamanızda Jetpack kitaplığı kullanma bölümünde açıklandığı gibi
googledeposunusettings.gradleöğesine ekleyin. - Uygulamanız veya modülünüz için build.gradle dosyasına ihtiyacınız olan yapılarla ilgili bağımlılıkları ekleyin:
- Not: En son kitaplık sürümü için webgpu | Jetpack | Android Developers sayfasını inceleyin.
androidx.webgpu kitaplığı, WebGPU NDK .so kitaplık dosyalarının yanı sıra yönetilen kod arayüzlerini içerir.
Kitaplık sürümünü güncellemek için build.gradle dosyanızı güncelleyebilir ve Android Studio'daki "Projeyi Senkronize Et" düğmesini kullanarak projenizi Gradle dosyalarıyla senkronize edebilirsiniz.
Üst düzey mimari
Android uygulamasında WebGPU oluşturma işlemi, kullanıcı arayüzünün yanıt verme özelliğini korumak için özel bir oluşturma iş parçacığında çalıştırılır.
- Kullanıcı arayüzü katmanı: Kullanıcı arayüzü, Jetpack Compose ile oluşturulur. WebGPU çizim yüzeyi,
AndroidExternalSurfacekullanılarak Compose hiyerarşisine entegre edilir. - Oluşturma Mantığı: Özel bir sınıf (ör. WebGpuRenderer), tüm WebGPU nesnelerini yönetmekten ve oluşturma döngüsünü koordine etmekten sorumludur.
- Gölgeleyici Katmanı: res veya dize sabitlerinde depolanan WGSL gölgeleyici kodu.
Adım adım: örnek uygulama
Bu bölümde, temel WebGPU iş akışını göstererek ekranda renkli bir üçgen oluşturmak için gereken temel adımlar açıklanmaktadır.
Ana Etkinlik
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WebGpuSurface()
}
}
}
The external surface Composable
WebgpuSurface.kt adlı yeni bir dosya oluşturun. Bu Composable, Compose ile oluşturucunuz arasında köprü oluşturmak için AndroidExternalSurface öğesini sarmalar.
@Composable
fun WebGpuSurface(modifier: Modifier = Modifier) {
// Create and remember a WebGpuRenderer instance.
val renderer = remember { WebGpuRenderer() }
AndroidExternalSurface(
modifier = modifier.fillMaxSize(),
) {
// This block is called when the surface is created or resized.
onSurface { surface, width, height ->
// Run the rendering logic on a background thread.
withContext(Dispatchers.Default) {
try {
// Initialize the renderer with the surface
renderer.init(surface, width, height)
// Render a frame.
renderer.render()
} finally {
// Clean up resources when the surface is destroyed.
renderer.cleanup()
}
}
}
}
}
Oluşturucuyu ayarlama
WebGpuRenderer.kt içinde WebGpuRenderer sınıfı oluşturun. Bu sınıf, GPU ile iletişim kurma işini üstlenir.
Öncelikle sınıf yapısını ve değişkenleri tanımlayın:
class WebGpuRenderer() {
private lateinit var webGpu: WebGpu
private lateinit var renderPipeline: GPURenderPipeline
}
Başlatma: Ardından, WebGPU örneğini oluşturmak ve yüzeyi yapılandırmak için init işlevini uygulayın. Bu işlev, daha önce oluşturduğumuz harici yüzey composable'ının içindeki AndroidExternalSurface kapsamı tarafından çağrılır.
Not: init işlevi, kurulumu kolaylaştırmak için yardımcı bir yöntem olan
createWebGpu'i (androidx.webgpu.helper'nin bir parçası) kullanır. Bu yardımcı program, WebGPU örneğini oluşturur, bir bağdaştırıcı seçer ve cihaz isteğinde bulunur.
// Inside WebGpuRenderer class
suspend fun init(surface: Surface, width: Int, height: Int) {
// 1. Create Instance & Device
webGpu = createWebGpu(surface)
val device = webGpu.device
// 2. Setup Pipeline (compile shaders)
initPipeline(device)
// 3. Configure the Surface
webGpu.webgpuSurface.configure(
GPUSurfaceConfiguration(
device,
width,
height,
TextureFormat.RGBA8Unorm,
)
)
}
androidx.webgpu kitaplığı, derleme sistemi tarafından otomatik olarak bağlanan ve yönetilen JNI ve .so dosyalarını içerir. Yardımcı yöntem
createWebGpu, paketlenmiş libwebgpu_c_bundled.so öğesinin yüklenmesini sağlar.
Ardışık düzen kurulumu
Artık bir cihazımız olduğuna göre GPU'ya üçgenimizi nasıl çizeceğini söylememiz gerekiyor. Bunu, gölgelendirici kodumuzu (WGSL ile yazılmış) içeren bir "ardışık düzen" oluşturarak yaparız.
Gölgelendiricileri derlemek ve oluşturma işlem hattını oluşturmak için bu özel yardımcı işlevi WebGpuRenderer sınıfınıza ekleyin.
// Inside WebGpuRenderer class
private fun initPipeline(device: GPUDevice) {
val shaderCode = """
@vertex fn vs_main(@builtin(vertex_index) vertexIndex : u32) ->
@builtin(position) vec4f {
const pos = array(vec2f(0.0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5));
return vec4f(pos[vertexIndex], 0, 1);
}
@fragment fn fs_main() -> @location(0) vec4f {
return vec4f(1, 0, 0, 1);
}
"""
// Create Shader Module
val shaderModule = device.createShaderModule(
GPUShaderModuleDescriptor(shaderSourceWGSL = GPUShaderSourceWGSL(shaderCode))
)
// Create Render Pipeline
renderPipeline = device.createRenderPipeline(
GPURenderPipelineDescriptor(
vertex = GPUVertexState(
shaderModule,
), fragment = GPUFragmentState(
shaderModule, targets = arrayOf(GPUColorTargetState(TextureFormat.RGBA8Unorm))
), primitive = GPUPrimitiveState(PrimitiveTopology.TriangleList)
)
)
}
Çerçeve çizme
İşlem hattı hazır olduğunda oluşturma işlevini uygulayabiliriz. Bu işlev, ekrandan bir sonraki kullanılabilir dokuyu alır, çizim komutlarını kaydeder ve bunları GPU'ya gönderir.
Bu yöntemi WebGpuRenderer sınıfınıza ekleyin:
// Inside WebGpuRenderer class
fun render() {
if (!::webGpu.isInitialized) {
return
}
val gpu = webGpu
// 1. Get the next available texture from the screen
val surfaceTexture = gpu.webgpuSurface.getCurrentTexture()
// 2. Create a command encoder
val commandEncoder = gpu.device.createCommandEncoder()
// 3. Begin a render pass (clearing the screen to blue)
val renderPass = commandEncoder.beginRenderPass(
GPURenderPassDescriptor(
colorAttachments = arrayOf(
GPURenderPassColorAttachment(
GPUColor(0.0, 0.0, 0.5, 1.0),
surfaceTexture.texture.createView(),
loadOp = LoadOp.Clear,
storeOp = StoreOp.Store,
)
)
)
)
// 4. Draw
renderPass.setPipeline(renderPipeline)
renderPass.draw(3) // Draw 3 vertices
renderPass.end()
// 5. Submit and Present
gpu.device.queue.submit(arrayOf(commandEncoder.finish()))
gpu.webgpuSurface.present()
}
Kaynak temizleme
Yüzey yok edildiğinde WebGpuSurface tarafından çağrılan temizleme işlevini uygulayın.
// Inside WebGpuRenderer class
fun cleanup() {
if (::webGpu.isInitialized) {
webGpu.close()
}
}
Oluşturulan çıkış
Örnek uygulama yapısı
Örnek uygulamada kullanılan yapıda olduğu gibi, oluşturma uygulamanızı kullanıcı arayüzü mantığınızdan ayırmak iyi bir uygulamadır:
app/src/main/
├── java/com/example/app/
│ ├── MainActivity.kt // Entry point
│ ├── WebGpuSurface.kt // Composable Surface
│ └── WebGpuRenderer.kt // Pure WebGPU logic
- MainActivity.kt: Uygulama giriş noktası. İçeriği
WebGpuSurfaceComposable olarak ayarlar. - WebGpuSurface.kt:
[AndroidExternalSurface](/reference/kotlin/androidx/compose/foundation/package-summary#AndroidExternalSurface(androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.unit.IntSize,androidx.compose.foundation.AndroidExternalSurfaceZOrder,kotlin.Boolean,kotlin.Function1))kullanarak kullanıcı arayüzü bileşenini tanımlar.Surfaceyaşam döngüsü kapsamını yönetir, yüzey hazır olduğunda oluşturucuyu başlatır ve yok edildiğinde temizler. - WebGpuRenderer.kt: WebGPU'ya özel tüm mantığı (cihaz oluşturma, ardışık düzen kurulumu) kapsar. Kullanıcı arayüzünden bağımsızdır ve yalnızca çizmek için gereken
[Surface](/reference/android/view/Surface.html)ve boyutları alır.
Yaşam döngüsü ve kaynak yönetimi
Yaşam döngüsü yönetimi, Jetpack Compose'da [AndroidExternalSurface](/reference/kotlin/androidx/compose/foundation/package-summary#AndroidExternalSurface(androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.ui.unit.IntSize,androidx.compose.foundation.AndroidExternalSurfaceZOrder,kotlin.Boolean,kotlin.Function1)) tarafından sağlanan Kotlin Coroutine kapsamı tarafından ele alınır.
- Yüzey Oluşturma:
onSurfacelambda bloğunun başındaDeviceveSurfaceyapılandırmasını başlatın. Bu kod,Surfacekullanılabilir hale geldiğinde hemen çalışır. - Yüzeyin Yok Edilmesi: Kullanıcı sayfadan ayrıldığında veya
Surfacesistem tarafından yok edildiğinde lambda bloğu iptal edilir. Bellek sızıntılarını önlemek içinrenderer.cleanup()çağrılarakfinallybloğu yürütülür. - Yeniden boyutlandırma: Yüzey boyutları değişirse
AndroidExternalSurface, yapılandırmaya bağlı olarak bloğu yeniden başlatabilir veya güncellemeleri doğrudan işleyebilir. Böylece oluşturucu her zaman geçerli bir arabelleğe yazar.
Hata ayıklama ve doğrulama
WebGPU, giriş yapılarını doğrulamak ve çalışma zamanı hatalarını yakalamak için tasarlanmış mekanizmalara sahiptir.
- Logcat: Doğrulama hataları Android Logcat'e yazdırılır.
- Hata Kapsamları: GPU komutlarını
[device.pushErrorScope()](/reference/kotlin/androidx/webgpu/GPUDevice#pushErrorScope(kotlin.Int))ve device.popErrorScope() blokları içine alarak belirli hataları yakalayabilirsiniz.
device.pushErrorScope(ErrorFilter.Validation)
// ... potentially incorrect code ...
device.popErrorScope { status, type, message ->
if (status == PopErrorScopeStatus.Success && type != ErrorType.NoError) {
Log.e("WebGPU", "Validation Error: $message")
}
}
Performans ipuçları
WebGPU'da programlama yaparken performans darboğazlarını önlemek için aşağıdakileri göz önünde bulundurun:
- Kare Başına Nesne Oluşturmaktan Kaçının: Yeniden kullanımı en üst düzeye çıkarmak için uygulama kurulumu sırasında bir kez işlem hatlarını (
GPURenderPipeline), bağlama grubu düzenlerini ve gölgelendirici modüllerini oluşturun. - Arabellek Kullanımını Optimize Etme: Her karede yeni arabellekler oluşturmak yerine
GPUQueue.writeBufferaracılığıyla mevcutGPUBuffersöğelerinin içeriğini güncelleyin. - Durum Değişikliklerini En Aza İndirme: Sürücü ek yükünü en aza indirmek ve oluşturma verimliliğini artırmak için aynı işlem hattını paylaşan ve bağlama gruplarını kullanan çizim çağrılarını gruplandırın.