Для использования Jetpack WebGPU ваш проект должен соответствовать следующим минимальным требованиям:
- Минимальный уровень API : требуется Android API 24 (Nougat) или выше.
- Аппаратное обеспечение : Для бэкэнда предпочтительны устройства, поддерживающие Vulkan 1.1+.
- Режим совместимости и поддержка OpenGL ES : Использование WebGPU в режиме совместимости возможно путем установки параметра standardized
featureLevelвcompatibilityпри запросеGPUAdapter.
// Example of requesting an adapter with "compatibility" mode enabled:
val adapter = instance.requestAdapter(
GPURequestAdapterOptions(featureLevel = FeatureLevel.Compatibility))
Установка и настройка
Предварительные требования:
Android Studio : Загрузите последнюю версию Android Studio с официального сайта и следуйте инструкциям, приведенным в руководстве по установке Android Studio .
Создать новый проект
После установки Android Studio выполните следующие шаги для настройки проекта WebGPU:
- Чтобы начать новый проект , откройте Android Studio и нажмите «Новый проект» .
Выберите шаблон : выберите шаблон «Пустая активность» в Android Studio и нажмите «Далее» .

Рисунок 1. Создание нового проекта в Android Studio. Настройте свой проект :
- Название : Дайте вашему проекту название (например, "JetpackWebGPUSample").
- Имя пакета : Убедитесь, что имя пакета соответствует выбранному вами пространству имен (например, com.example.webgpuapp).
- Язык : Выберите Kotlin .
- Минимальные требования к SDK : выберите API 24: Android 7.0 (Nougat) или выше, как рекомендуется для этой библиотеки.
- Язык конфигурации сборки : Для современного управления зависимостями рекомендуется использовать Kotlin DSL (build.gradle.kts) .

Рисунок 2. Начало с пустой активности. Завершение : Нажмите «Завершить» и дождитесь синхронизации файлов проекта в Android Studio.
Добавить библиотеку WebGPU Jetpack
- Добавьте репозиторий
googleвsettings.gradle, как описано в разделе «Использование библиотеки Jetpack в вашем приложении». - Добавьте зависимости для необходимых артефактов в файл build.gradle вашего приложения или модуля:
- Примечание : Проверьте webgpu | Jetpack | Android Developers , чтобы узнать последнюю версию библиотеки.
Библиотека androidx.webgpu содержит файлы библиотеки WebGPU NDK .so, а также интерфейсы управляемого кода.
Вы можете обновить версию библиотеки, обновив файл build.gradle и синхронизировав проект с файлами gradle с помощью кнопки "Синхронизировать проект" в Android Studio.
Архитектура высокого уровня
В приложениях Android рендеринг с использованием WebGPU выполняется в выделенном потоке для обеспечения отзывчивости пользовательского интерфейса.
- Слой пользовательского интерфейса : Пользовательский интерфейс создан с помощью Jetpack Compose. В иерархию Compose интегрирована поверхность для отрисовки WebGPU с использованием
AndroidExternalSurface. - Логика рендеринга : специализированный класс (например, WebGpuRenderer) отвечает за управление всеми объектами WebGPU и координацию цикла рендеринга.
- Шейдерный слой : код шейдера WGSL, хранящийся в константах типа res или string.
Пошаговое руководство: пример приложения
В этом разделе подробно описаны основные шаги, необходимые для отображения цветного треугольника на экране, и продемонстрирован базовый рабочий процесс WebGPU.
Основная деятельность
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WebGpuSurface()
}
}
}
Внешняя поверхность Композитная
Создайте новый файл с именем WebgpuSurface.kt. Этот Composable будет обертывать AndroidExternalSurface , обеспечивая связь между Compose и вашим рендерером.
@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()
}
}
}
}
}
Настройте рендерер
Создайте класс WebGpuRenderer в WebGpuRenderer.kt . Этот класс возьмет на себя основную работу по взаимодействию с графическим процессором.
Сначала определите структуру класса и переменные:
class WebGpuRenderer() {
private lateinit var webGpu: WebGpu
private lateinit var renderPipeline: GPURenderPipeline
}
Инициализация: Далее реализуйте функцию init для создания экземпляра WebGPU и настройки поверхности. Эта функция вызывается из области видимости AndroidExternalSurface внутри созданного ранее внешнего составного объекта поверхности.
Примечание: Функция инициализации использует метод createWebGpu , вспомогательный метод (часть androidx.webgpu.helper ), упрощающий настройку. Эта утилита создает экземпляр WebGPU, выбирает адаптер и запрашивает устройство.
// 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 включает файлы JNI и .so , которые автоматически связываются и управляются системой сборки. Вспомогательный метод createWebGpu отвечает за загрузку встроенной библиотеки libwebgpu_c_bundled.so .
Настройка конвейера
Теперь, когда у нас есть устройство, нам нужно сообщить графическому процессору, как нарисовать наш треугольник. Мы делаем это, создавая «конвейер», содержащий наш шейдерный код (написанный на языке WGSL).
Добавьте эту приватную вспомогательную функцию в ваш класс WebGpuRenderer , чтобы скомпилировать шейдеры и создать конвейер рендеринга.
// 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)
)
)
}
Нарисуйте рамку
Теперь, когда конвейер готов, мы можем реализовать функцию рендеринга. Эта функция получает следующую доступную текстуру с экрана, записывает команды отрисовки и отправляет их на графический процессор.
Добавьте этот метод в ваш класс WebGpuRenderer :
// 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()
}
Очистка ресурсов
Реализуйте функцию очистки, которая вызывается компонентом WebGpuSurface при разрушении поверхности.
// Inside WebGpuRenderer class
fun cleanup() {
if (::webGpu.isInitialized) {
webGpu.close()
}
}
Отрендеренный результат

Пример структуры приложения
Рекомендуется разделять реализацию отрисовки от логики пользовательского интерфейса, как это показано в примере приложения:
app/src/main/
├── java/com/example/app/
│ ├── MainActivity.kt // Entry point
│ ├── WebGpuSurface.kt // Composable Surface
│ └── WebGpuRenderer.kt // Pure WebGPU logic
- MainActivity.kt : Точка входа в приложение. Она устанавливает содержимое для объекта
WebGpuSurfaceComposable. - 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)). Он управляет областью жизненного циклаSurface, инициализируя рендерер, когда поверхность готова, и выполняя очистку при ее уничтожении. - WebGpuRenderer.kt : Инкапсулирует всю логику, специфичную для WebGPU (создание устройства, настройка конвейера). Он отделен от пользовательского интерфейса, получая только
[Surface](/reference/android/view/Surface.html)и необходимые для отрисовки размеры.
Управление жизненным циклом и ресурсами
Управление жизненным циклом осуществляется в рамках области видимости Kotlin Coroutine, предоставляемой [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)) в Jetpack Compose.
- Создание Surface : Инициализируйте конфигурацию
DeviceиSurfaceв начале блока лямбда-функцииonSurface. Этот код выполняется немедленно, как толькоSurfaceстановится доступным. - Уничтожение поверхности : Когда пользователь переходит на другую страницу или
Surfaceуничтожается системой, блок лямбда-функции отменяется. Выполняется блокfinally, вызывающийrenderer.cleanup()для предотвращения утечек памяти. - Изменение размера : Если размеры поверхности изменяются,
AndroidExternalSurfaceможет перезапустить блок или напрямую обрабатывать обновления в зависимости от конфигурации, поэтому рендерер всегда записывает данные в действительный буфер.
Отладка и проверка
WebGPU имеет механизмы, предназначенные для проверки входных структур и выявления ошибок во время выполнения.
- Logcat: Ошибки проверки выводятся в Android Logcat.
- Области ошибок: Вы можете перехватывать конкретные ошибки, инкапсулируя команды GPU в блоки
[device.pushErrorScope()](/reference/kotlin/androidx/webgpu/GPUDevice#pushErrorScope(kotlin.Int))и ` device.popErrorScope()` .
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")
}
}
Советы по повышению производительности
При программировании с использованием WebGPU следует учитывать следующие факторы, чтобы избежать узких мест в производительности:
- Избегайте создания объектов для каждого кадра : создавайте экземпляры конвейеров (
GPURenderPipeline), привязывайте компоновку групп и модули шейдеров один раз во время настройки приложения, чтобы максимально увеличить повторное использование. - Оптимизация использования буферов : обновляйте содержимое существующих
GPUBuffersс помощьюGPUQueue.writeBufferвместо создания новых буферов для каждого кадра. - Минимизация изменений состояния : группируйте вызовы отрисовки, использующие один и тот же конвейер, и связывайте группы, чтобы минимизировать накладные расходы драйвера и повысить эффективность рендеринга.