This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: skiko-gpu-surface-detach-guardrail

Compose Multiplatform Skiko GPU Surface Detach Lifecycle Synchronization

Enforces synchronous GPU fence completion and deterministic native surface teardown during Compose Multiplatform view transitions and window detachment. Prevents VK_ERROR_DEVICE_LOST, Metal command buffer failures, and catastrophic native Skia context memory leaks caused by tearing down surfaces with inflight draw calls.

Prohibited Anti-Pattern: Asynchronous or Unsynchronized View Teardown Corrupting Native Skia/Skiko GPU State

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Compose Multiplatform Skiko GPU Surface Detach Lifecycle Synchronization - Enforces synchronous GPU fence completion and deterministic native surface teardown during Compose Multiplatform view transitions and window detachment. Prevents VK_ERROR_DEVICE_LOST, Metal command buffer failures, and catastrophic native Skia context memory leaks caused by tearing down surfaces with inflight draw calls.
globs: **/*View.kt, **/*ViewController.kt, **/*Layer.kt, **/platform/**/*.kt, **/graphics/**/*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/skiko-gpu-surface-detach-guardrail"
---

# Compose Multiplatform Skiko GPU Surface Detach Lifecycle Synchronization

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Asynchronous or Unsynchronized View Teardown Corrupting Native Skia/Skiko GPU State

## System Constraints
You are a Principal Mobile Graphics Architect enforcing strict native GPU fence synchronization during Compose Multiplatform Skiko surface destruction. You must mandate deterministic GPU queue draining and surface detach invariants across iOS (Metal) and Android/Desktop (Vulkan/OpenGL) to eradicate device-lost faults and native Skia heap corruption.

## Strict Guidelines
- Engineers MUST ALWAYS explicitly flush pending graphics commands via Skia DirectContext.flushAndSubmit(sync = true) before detaching the underlying platform view or CAMetalLayer/ANativeWindow.
- Engineers MUST NOT destroy or nullify Skia Surface, RenderTarget, or Skiko native contexts while GPU fences or command buffers are inflight.
- Engineers MUST wrap view lifecycle teardown routines (e.g., UIViewController.viewWillDisappear, ComponentCallbacks2.onTrimMemory) in synchronous dispatch queues that guarantee graphics hardware pipeline completion before releasing native backing pointers.
- Engineers MUST implement explicit invalidation hooks on SkiaLayer when transitioning between navigation destinations to cancel active redraw requests before surface disposal.
- Native rendering layers MUST invoke SkiaLayer.dispose() or SkikoRenderTarget.release() on the designated graphics rendering thread, NEVER asynchronously from arbitrary coroutine contexts or unmanaged background threads.

## Bad vs Good Implementations
### Synchronized Skiko Metal Surface Teardown on iOS View Detach

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Disposing the SkiaLayer directly during viewWillDisappear without draining in-flight Metal command buffers causes the GPU to write to an unbacked or invalidated CAMetalDrawable, generating EXC_BAD_ACCESS or VK_ERROR_DEVICE_LOST.
```kotlin
import platform.UIKit.UIViewController
import org.jetbrains.skiko.SkiaLayer

class ComposeMetalViewController(private val skiaLayer: SkiaLayer) : UIViewController(null, null) {
    override fun viewWillDisappear(animated: Boolean) {
        super.viewWillDisappear(animated)
        // ANTI-PATTERN: Asynchronously releasing SkiaLayer while Metal command encoders are in-flight.
        // Leads to CAMetalLayer presentation on invalid drawable and native crash.
        skiaLayer.dispose()
    }
}
```

#### Production Standard (Correct)
> **Standard**: Flushing with syncCpu = true forces the CPU to wait until the GPU fence signals completion of all active draw commands, ensuring the CAMetalLayer and Skia render target can be safely detached and disposed without pipeline faults.
```kotlin
import platform.UIKit.UIViewController
import org.jetbrains.skiko.SkiaLayer
import org.jetbrains.skia.DirectContext

class ComposeMetalViewController(
    private val skiaLayer: SkiaLayer,
    private val directContext: DirectContext?
) : UIViewController(null, null) {
    override fun viewWillDisappear(animated: Boolean) {
        // 1. Immediately pause redraw to halt enqueueing new frame dispatches
        skiaLayer.needRedraw()
        
        // 2. Synchronously flush and submit all pending work to GPU fences
        directContext?.flushAndSubmit(syncCpu = true)
        
        // 3. Deterministically detach surface and dispose resources
        skiaLayer.detach()
        skiaLayer.dispose()
        
        super.viewWillDisappear(animated)
    }
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Compose Multiplatform Skiko GPU Surface Detach Lifecycle Synchronization

Compose Multiplatform Skiko GPU Surface Detach Lifecycle Synchronization defines an industrial-grade behavioral standard for mobile engineering. Enforces synchronous GPU fence completion and deterministic native surface teardown during Compose Multiplatform view transitions and window detachment. Prevents VK_ERROR_DEVICE_LOST, Metal command buffer failures, and catastrophic native Skia context memory leaks caused by tearing down surfaces with inflight draw calls. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Asynchronous or Unsynchronized View Teardown Corrupting Native Skia/Skiko GPU State Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftAsynchronous or Unsynchronized View Teardown Corrupting Native Skia/Skiko GPU StateCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS explicitly flush pending graphics commands via Skia DirectContext.flushAndSubmit(sync = true) before detaching the underlying platform view or CAMetalLayer/ANativeWindow.

Engineers MUST ALWAYS explicitly flush pending graphics commands via Skia DirectContext.flushAndSubmit(sync = true) before detaching the underlying platform view or CAMetalLayer/ANativeWindow.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT destroy or nullify Skia Surface, RenderTarget, or Skiko native contexts while GPU fences or command buffers are inflight.

Engineers MUST NOT destroy or nullify Skia Surface, RenderTarget, or Skiko native contexts while GPU fences or command buffers are inflight.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST wrap view lifecycle teardown routines (e.g., UIViewController.viewWillDisappear, ComponentCallbacks2.onTrimMemory) in synchronous dispatch queues that guarantee graphics hardware pipeline completion before releasing native backing pointers.

Engineers MUST wrap view lifecycle teardown routines (e.g., UIViewController.viewWillDisappear, ComponentCallbacks2.onTrimMemory) in synchronous dispatch queues that guarantee graphics hardware pipeline completion before releasing native backing pointers.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Engineers MUST implement explicit invalidation hooks on SkiaLayer when transitioning between navigation destinations to cancel active redraw requests before surface disposal.

Engineers MUST implement explicit invalidation hooks on SkiaLayer when transitioning between navigation destinations to cancel active redraw requests before surface disposal.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Native rendering layers MUST invoke SkiaLayer.dispose() or SkikoRenderTarget.release() on the designated graphics rendering thread, NEVER asynchronously from arbitrary coroutine contexts or unmanaged background threads.

Native rendering layers MUST invoke SkiaLayer.dispose() or SkikoRenderTarget.release() on the designated graphics rendering thread, NEVER asynchronously from arbitrary coroutine contexts or unmanaged background threads.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Compose Multiplatform Skiko GPU Surface Detach Lifecycle Synchronization critical for AI coding assistants?

Enforces synchronous GPU fence completion and deterministic native surface teardown during Compose Multiplatform view transitions and window detachment. Prevents VK_ERROR_DEVICE_LOST, Metal command buffer failures, and catastrophic native Skia context memory leaks caused by tearing down surfaces with inflight draw calls. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Asynchronous or Unsynchronized View Teardown Corrupting Native Skia/Skiko GPU State) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related MOBILE Rules

View all rules →
1 Rule in Stack

Compose