Sample CodeiOS, iPadOS, Mac Catalyst, macOSReviewed 2026-07-21View on Apple Developer

Adjusting the level of detail using Metal mesh shaders

At a glance

Item Summary
Purpose Choose and render meshes with several levels of detail using object and mesh shaders.
App architecture C++, Objective-C, Objective-C++ host code with Metal shaders; Python is build/tooling support; AAPLViewController hands work to AAPLRendererAdapter, which owns metal-cpp renderer through an Objective-C++ adapter before object and mesh shader stages.
Main patterns Adapter, View-controller organization, Host-shader data contract
Scope High-level review of 13 scanned source files and 17 detected declarations; build assets are omitted.

Project structure

Source bundle/
└── MeshShadersMetalCPP/
    ├── Renderer/
    │   ├── AAPLRenderer.cpp
    │   ├── AAPLShaders.metal
    │   └── AAPLShaderTypes.h
    ├── Adapter/
    │   └── AAPLRendererAdapter.mm
    └── Application/
        ├── main.m
        ├── AAPLViewController.m
        ├── WindowSceneDelegate.m
        ├── AAPLAppDelegate.h
        └── AAPLAppDelegate.m

Structure observations

  • The entry/composition boundary and renderer or operation boundary are separate in the source; AAPLRendererAdapter is the principal feature coordinator.
  • GPU-specific logic stays in Metal shader files; shared headers bridge host/shader layouts where present.
  • The tree above is intentionally pruned to composition, resource, and shader files.

Overall architecture

Reference code

MeshShadersMetalCPP/Renderer/AAPLRenderer.cpp:468 — feature handoff or setup anchor

    pRenderEncoder->drawMeshThreadgroups(MTL::Size(AAPLNumObjectsX, AAPLNumObjectsY, AAPLNumObjectsZ),
                                         MTL::Size(AAPLMaxTotalThreadsPerObjectThreadgroup, 1, 1),
                                         MTL::Size(AAPLMaxTotalThreadsPerMeshThreadgroup, 1, 1));

    pRenderEncoder->endEncoding();
    pCommandBuffer->presentDrawable(pView->currentDrawable());
    pCommandBuffer->commit();

Interpretation

This is the dominant control/data path: platform code composes AAPLRendererAdapter; that object controls metal-cpp renderer through an Objective-C++ adapter; GPU-visible work ends in object and mesh shader stages. The arrows summarize responsibility transfer, not a claim that every node directly calls the next.

Ownership and state

Ownership evidence

MeshShadersMetalCPP/Adapter/AAPLRendererAdapter.mm:39AAPLRendererAdapter creates and stores _pRenderer

@implementation AAPLRendererAdapter
// ...
        _pRenderer = new AAPLRenderer( *((__bridge MTK::View *)pMtkView) );
// ...
@end
Owner Object or state Relationship Mutation authority
AAPLRendererAdapter _pRenderer / AAPLRenderer Creates and stores; the diagram uses composition because construction is source-visible. The declaring scope performs setup and replacement.
AAPLRendererAdapter Feature-specific framework and Metal resources Operation-local calls or stored state; exclusive lifetime is not assumed beyond cited evidence. Feature setup/encoding code controls mutation and command submission.

Class and protocol design

Type Responsibility Depends on or conforms to Source
AAPLViewController selects/configures the view and composes the feature objects. PlatformViewController MeshShadersMetalCPP/Application/AAPLViewController.h:24
AAPLRendererAdapter bridges UI/framework callbacks into a differently shaped renderer API. NSObject MeshShadersMetalCPP/Adapter/AAPLRendererAdapter.h:13
AAPLAppDelegate handles application/window lifecycle callbacks. PlatformAppDelegate MeshShadersMetalCPP/Application/AAPLAppDelegate.h:26
WindowSceneDelegate handles application/window lifecycle callbacks. UIResponder, UIWindowSceneDelegate MeshShadersMetalCPP/Application/WindowSceneDelegate.h:15

Framework delegate conformance is a callback seam; the source does not justify calling the whole app protocol-oriented.

Access control

Symbol Access Verified effect Design reason
AAPLRendererAdapter header-visible available to translation units that import the header; this is not Swift public. Keep the usable surface no wider than the collaboration requires. (MeshShadersMetalCPP/Adapter/AAPLRendererAdapter.h:13)
AAPLRendererAdapter implementation details implementation-only native helpers, stored state, or registration code stays out of the imported header contract. Hide native implementation details from importing translation units. (MeshShadersMetalCPP/Adapter/AAPLRendererAdapter.mm:1)
AAPLRendererAdapter C++ implementation header/implementation boundary the implementation file contains native details not exported as a Swift-style public API. Keep the usable surface no wider than the collaboration requires. (MeshShadersMetalCPP/Adapter/AAPLRendererAdapter.mm:1)
AAPLShaders entry points Metal library boundary host code resolves named shader entry points; Swift access modifiers do not apply. Expose only named shader entry points needed by pipeline creation. (MeshShadersMetalCPP/Renderer/AAPLShaders.metal:17)

This sample does not use Swift private, fileprivate, or public for its native boundary. Objective-C/Objective-C++ use header versus implementation placement, C++ uses access specifiers/linkage, Python uses module conventions, and Metal entry points cross a compiled-library boundary; these are not Swift access levels.

Logic ownership and placement

Logic Owning type or file Why it lives there
Selects/configures the view and composes the feature objects AAPLViewControllerMeshShadersMetalCPP/Application/AAPLViewController.h:24 The type’s callbacks and stored state align with this responsibility.
Bridges UI/framework callbacks into a differently shaped renderer API AAPLRendererAdapterMeshShadersMetalCPP/Adapter/AAPLRendererAdapter.h:13 The type’s callbacks and stored state align with this responsibility.
Handles application/window lifecycle callbacks AAPLAppDelegateMeshShadersMetalCPP/Application/AAPLAppDelegate.h:26 The type’s callbacks and stored state align with this responsibility.
Handles application/window lifecycle callbacks WindowSceneDelegateMeshShadersMetalCPP/Application/WindowSceneDelegate.h:15 The type’s callbacks and stored state align with this responsibility.
Metal-cpp renderer through an Objective-C++ adapter AAPLRendererAdapter / MeshShadersMetalCPP/Renderer/AAPLRenderer.cpp:468 Keeps Metal/framework setup and encoding out of entry or lifecycle code.
Object and mesh shader stages MeshShadersMetalCPP/Renderer/AAPLShaders.metal:81 GPU-parallel code remains in the Metal compilation boundary.

Shader boundary reference

MeshShadersMetalCPP/Renderer/AAPLShaders.metal:81 — representative GPU entry/helper

[[object, max_total_threads_per_threadgroup(AAPLMaxTotalThreadsPerObjectThreadgroup), max_total_threadgroups_per_mesh_grid(AAPLMaxThreadgroupsPerMeshGrid)]]
void meshShaderObjectStageFunction(object_data payload_t& payload            [[payload]],
                                   mesh_grid_properties meshGridProperties,
                                   constant AAPLMeshInfo* meshes             [[buffer(AAPLBufferIndexMeshInfo)]],
                                   constant AAPLVertex* vertices             [[buffer(AAPLBufferIndexMeshVertices)]],
                                   constant AAPLIndexType* indices           [[buffer(AAPLBufferIndexMeshIndices)]],
                                   constant float4x4*   transforms           [[buffer(AAPLBufferIndexTransforms)]],
                                   constant float3*     colors               [[buffer(AAPLBufferIndexMeshColor)]],
                                   constant float4x4&   viewProjectionMatrix [[buffer(AAPLBufferViewProjectionMatrix)]],
                                   constant uint&       lod                  [[buffer(AAPLBufferIndexLODChoice)]],
                                   uint3                positionInGrid       [[threadgroup_position_in_grid]])
{
    // ...
}

Design patterns

Pattern Source evidence Purpose or tradeoff
Adapter MeshShadersMetalCPP/Adapter/AAPLRendererAdapter.mm:12 An adapter translates platform view callbacks or Objective-C objects into C++/metal-cpp calls.
View-controller organization MeshShadersMetalCPP/Application/AAPLViewController.h:14 Makes the sample’s metal-cpp renderer through an Objective-C++ adapter an explicit, reviewable boundary.
Host-shader data contract MeshShadersMetalCPP/Renderer/AAPLRenderer.cpp:447 Shared indices/structs and matching bindings couple host encoding to shader signatures deliberately.

Naming conventions

  • Role suffixes make ownership visible: AAPLViewController, AAPLRendererAdapter, AAPLAppDelegate, WindowSceneDelegate.
  • Method names describe setup or encoding actions: initWithMtkView, dealloc, device, drawInMTKView, drawableSizeWillChange, setRotationSpeed, setTranslation.
  • Shader entry points use stage/operation names: fragmentShader, meshShaderObjectStageFunction, meshShaderMeshStageFunctionPoints, meshShaderMeshStageFunctionLines, meshShaderMeshStageFunction.
  • AAPL is a sample namespace prefix, not a recommendation for production module naming; retain semantic suffixes such as Renderer, Manager, Scene, or Adapter.

Architecture takeaways

  • Keep AAPLViewController focused on composition; AAPLRendererAdapter is the owner of metal-cpp renderer through an Objective-C++ adapter.
  • Treat object and mesh shader stages as a separate execution/compilation boundary with explicit resource and data-layout contracts.
  • The verified ownership edge is AAPLRendererAdapter_pRenderer; broader exclusive ownership is not inferred.
  • Access-control rationale follows concrete language boundaries rather than translating every header or shader symbol into Swift terms.

Source map

Source file Architectural role
MeshShadersMetalCPP/Renderer/AAPLRenderer.cpp entry point or feature implementation
MeshShadersMetalCPP/Adapter/AAPLRendererAdapter.mm AAPLRendererAdapter, AAPLRendererAdapter
MeshShadersMetalCPP/Renderer/AAPLShaders.metal vertexOut, pointVertexOut, payload_t, primOut, fragmentIn
MeshShadersMetalCPP/Application/main.m entry point or feature implementation
MeshShadersMetalCPP/Application/AAPLViewController.m AAPLViewController
MeshShadersMetalCPP/Application/WindowSceneDelegate.m WindowSceneDelegate
MeshShadersMetalCPP/Renderer/AAPLShaderTypes.h entry point or feature implementation
MeshShadersMetalCPP/Application/AAPLAppDelegate.h AAPLAppDelegate
MeshShadersMetalCPP/Application/AAPLAppDelegate.m AAPLAppDelegate, AAPLAppDelegate