Sample CodeReviewed 2026-07-21View on Apple Developer

Creating a 3D application with hydra rendering

At a glance

Item Summary
Purpose Build a 3D application that integrates with Hydra and USD.
App architecture Objective-C++ host code with Metal shaders; Python is build/tooling support; AAPLViewController hands work to AAPLRenderer, which owns Objective-C++ Hydra renderer integration before Hydra render delegate backed by Metal.
Main patterns Renderer boundary, Framework adapter, View-controller organization
Scope High-level review of 12 scanned source files and 10 detected declarations; build assets are omitted.

Project structure

Source bundle/
└── source/
    ├── AAPLRenderer.mm
    ├── AAPLViewController.mm
    ├── BlitShaders.metal
    ├── main.mm
    ├── AAPLAppDelegate.h
    ├── AAPLAppDelegate.mm
    ├── AAPLRenderer.h
    ├── AAPLViewController.h
    └── AAPLCamera.h

Structure observations

  • The entry/composition boundary and renderer or operation boundary are separate in the source; AAPLRenderer 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

source/AAPLRenderer.mm:368 — feature handoff or setup anchor

    HgiMetal* hgi = static_cast<HgiMetal*>(_hgi.get());
    hgi->StartFrame();
    
    // Draw the scene using Hydra, and recast the result to a MTLTexture.
    CGSize viewSize = [view drawableSize];
    HgiTextureHandle hgiTexture = [self drawWithHydraAt:timeCode viewSize:viewSize];
    id<MTLTexture> texture = static_cast<HgiMetalTexture*>(hgiTexture.Get())->GetTextureId();

Interpretation

This is the dominant control/data path: platform code composes AAPLRenderer; that object controls Objective-C++ Hydra renderer integration; GPU-visible work ends in Hydra render delegate backed by Metal. The arrows summarize responsibility transfer, not a claim that every node directly calls the next.

Ownership and state

Ownership evidence

source/AAPLViewController.mm:35AAPLViewController creates and stores _renderer

@implementation AAPLViewController
// ...
    _renderer = [[AAPLRenderer alloc] initWithMetalKitView:_view];
// ...
@end
Owner Object or state Relationship Mutation authority
AAPLViewController _renderer / AAPLRenderer Creates and stores; the diagram uses composition because construction is source-visible. The declaring scope performs setup and replacement.
AAPLRenderer 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. NSViewController source/AAPLViewController.h:15
AAPLRenderer owns pipeline/resource setup and per-frame command encoding. NSObject, MTKViewDelegate source/AAPLRenderer.h:14
AAPLAppDelegate handles application/window lifecycle callbacks. NSObject, NSApplicationDelegate source/AAPLAppDelegate.h:12
AAPLCamera translates Hydra camera state and user pan, rotation, and zoom input into render parameters. NSObject, NSMutableCopying source/AAPLCamera.mm:18

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
AAPLAppDelegate 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. (source/AAPLAppDelegate.h:12)
AAPLRenderer 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. (source/AAPLRenderer.mm:1)
BlitShaders 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. (source/BlitShaders.metal:17)
cleanup_schema Python module boundary the script is build/tooling support, not part of the runtime app object graph. Keep the usable surface no wider than the collaboration requires. (scripts/cleanup_schema.py:1)

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 AAPLViewControllersource/AAPLViewController.h:15 The type’s callbacks and stored state align with this responsibility.
Owns pipeline/resource setup and per-frame command encoding AAPLRenderersource/AAPLRenderer.h:14 The type’s callbacks and stored state align with this responsibility.
Handles application/window lifecycle callbacks AAPLAppDelegatesource/AAPLAppDelegate.h:12 The type’s callbacks and stored state align with this responsibility.
Objective-C++ Hydra renderer integration AAPLRenderer / source/AAPLRenderer.mm:368 Keeps Metal/framework setup and encoding out of entry or lifecycle code.
Hydra render delegate backed by Metal source/BlitShaders.metal:17 GPU-parallel code remains in the Metal compilation boundary.

Shader boundary reference

source/BlitShaders.metal:17 — full-screen blit vertex entry point

vertex VertexOut vtxBlit(uint vid [[vertex_id]])
{
    // ...
}

Design patterns

Pattern Source evidence Purpose or tradeoff
Renderer boundary source/AAPLRenderer.mm:368 UI/lifecycle code composes a renderer while GPU state and encoding stay together.
Framework adapter source/AAPLViewController.mm:35 Makes the sample’s Objective-C++ Hydra renderer integration an explicit, reviewable boundary.
View-controller organization source/AAPLViewController.h:15 Makes the sample’s Objective-C++ Hydra renderer integration an explicit, reviewable boundary.

Naming conventions

  • Role suffixes make ownership visible: AAPLViewController, AAPLRenderer, AAPLAppDelegate.
  • Method names describe setup or encoding actions: applicationDidFinishLaunching, applicationWillTerminate, applicationShouldTerminateAfterLastWindowClosed, initWithMetalKitView, setupScene, requestFrame, initializeMaterial.
  • Shader entry points use stage/operation names: vtxBlit, fragBlitLinear.
  • 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; AAPLRenderer is the owner of Objective-C++ Hydra renderer integration.
  • Treat Hydra render delegate backed by Metal as a separate execution/compilation boundary with explicit resource and data-layout contracts.
  • The verified ownership edge is AAPLViewController_renderer; 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
source/AAPLRenderer.mm AAPLRenderer
source/AAPLViewController.mm AAPLViewController
source/BlitShaders.metal VertexOut
source/main.mm entry point or feature implementation
source/AAPLAppDelegate.h AAPLAppDelegate
source/AAPLAppDelegate.mm AAPLAppDelegate, AAPLAppDelegate
source/AAPLRenderer.h AAPLRenderer
source/AAPLViewController.h AAPLViewController
source/AAPLCamera.h AAPLCamera