At a glance
| Item |
Summary |
| Purpose |
Draw with Metal and OpenGL in the same view using an interoperable texture. |
| App architecture |
Objective-C host code with Metal shaders; AAPLMetalViewController hands work to AAPLMetalRenderer, which owns separate Metal and OpenGL renderers before shared-view interoperability and presentation. |
| Main patterns |
Adapter, Backend isolation, Shared resource boundary |
| Scope |
High-level review of 20 scanned source files and 16 detected declarations; build assets are omitted. |
Project structure
Source bundle/
├── Application/
│ ├── AAPLOpenGLMetalInteropTexture.m
│ ├── AAPLOpenGLViewController.m
│ ├── main.m
│ ├── WindowSceneDelegate.m
│ ├── AAPLAppDelegate.h
│ └── AAPLOpenGLViewController.h
└── Renderer/
└── Metal/
├── AAPLShaders.metal
├── AAPLMetalRenderer.m
└── AAPLShaderTypes.h
Structure observations
- The entry/composition boundary and renderer or operation boundary are separate in the source;
AAPLMetalRenderer 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
flowchart LR
N1["AAPLMetalViewController"]
N2["AAPLMetalRenderer"]
N3["separate Metal and OpenGL renderers"]
N4["shared-view interoperability and presentation"]
N1 --> N2
N2 --> N3
N3 --> N4
Reference code
Application/AAPLOpenGLMetalInteropTexture.m:187 — Core Video texture bridge between APIs
cvret = CVMetalTextureCacheCreate(
kCFAllocatorDefault,
nil,
_metalDevice,
nil,
&_CVMTLTextureCache);
NSAssert(cvret == kCVReturnSuccess, @"Failed to create Metal texture cache");
Interpretation
This is the dominant control/data path: platform code composes AAPLMetalRenderer; that object controls separate Metal and OpenGL renderers; GPU-visible work ends in shared-view interoperability and presentation. The arrows summarize responsibility transfer, not a claim that every node directly calls the next.
Ownership and state
classDiagram
AAPLOpenGLViewController *-- AAPLOpenGLRenderer : _openGLRenderer
Ownership evidence
Application/AAPLOpenGLViewController.m:55 — AAPLOpenGLViewController creates and stores _openGLRenderer
_openGLRenderer = [[AAPLOpenGLRenderer alloc] initWithDefaultFBOName:_defaultFBOName];
NSAssert(_openGLRenderer, @"OpenGL Renderer failed initialization");
_metalDevice = MTLCreateSystemDefaultDevice();
_metalRenderer = [[AAPLMetalRenderer alloc] initWithDevice:_metalDevice
colorPixelFormat:AAPLOpenGLViewInteropPixelFormat];
| Owner |
Object or state |
Relationship |
Mutation authority |
AAPLOpenGLViewController |
_openGLRenderer / AAPLOpenGLRenderer |
Creates and stores; the diagram uses composition because construction is source-visible. |
The declaring scope performs setup and replacement. |
AAPLMetalRenderer |
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 |
AAPLMetalViewController |
selects/configures the view and composes the feature objects. |
PlatformViewController, MTKViewDelegate |
Application/AAPLMetalViewController.h:20 |
AAPLOpenGLViewController |
selects/configures the view and composes the feature objects. |
PlatformViewController |
Application/AAPLOpenGLViewController.h:22 |
AAPLMetalRenderer |
owns pipeline/resource setup and per-frame command encoding. |
NSObject |
Renderer/Metal/AAPLMetalRenderer.h:11 |
AAPLOpenGLRenderer |
owns pipeline/resource setup and per-frame command encoding. |
NSObject |
Renderer/OpenGL/AAPLOpenGLRenderer.h:15 |
AAPLOpenGLView |
owns presentation timing/drawable behavior and forwards callbacks. |
PlatformViewBase |
Application/AAPLOpenGLViewController.h:18 |
AAPLAppDelegate |
handles application/window lifecycle callbacks. |
UIResponder, UIApplicationDelegate |
Application/AAPLAppDelegate.h:10 |
WindowSceneDelegate |
handles application/window lifecycle callbacks. |
UIResponder, UIWindowSceneDelegate |
Application/WindowSceneDelegate.h:11 |
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. (Application/AAPLAppDelegate.h:10) |
AAPLMetalRenderer 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. (Renderer/Metal/AAPLMetalRenderer.m: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. (Renderer/Metal/AAPLShaders.metal:22) |
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 |
AAPLMetalViewController — Application/AAPLMetalViewController.h:20 |
The type’s callbacks and stored state align with this responsibility. |
| Selects/configures the view and composes the feature objects |
AAPLOpenGLViewController — Application/AAPLOpenGLViewController.h:22 |
The type’s callbacks and stored state align with this responsibility. |
| Owns pipeline/resource setup and per-frame command encoding |
AAPLMetalRenderer — Renderer/Metal/AAPLMetalRenderer.h:11 |
The type’s callbacks and stored state align with this responsibility. |
| Owns pipeline/resource setup and per-frame command encoding |
AAPLOpenGLRenderer — Renderer/OpenGL/AAPLOpenGLRenderer.h:15 |
The type’s callbacks and stored state align with this responsibility. |
| Separate Metal and OpenGL renderers |
AAPLMetalRenderer / Application/AAPLOpenGLMetalInteropTexture.m:50 |
Keeps Metal/framework setup and encoding out of entry or lifecycle code. |
| Shared-view interoperability and presentation |
Renderer/Metal/AAPLShaders.metal:22 |
GPU-parallel code remains in the Metal compilation boundary. |
Shader boundary reference
Renderer/Metal/AAPLShaders.metal:22 — representative GPU entry/helper
vertex ColorInOut vertexShader( uint vertexID [[ vertex_id ]],
const device AAPLVertex * in [[ buffer(AAPLBufferIndexVertices) ]],
constant AAPLUniforms & uniforms [[ buffer(AAPLBufferIndexUniforms) ]])
{
// ...
}
Design patterns
| Pattern |
Source evidence |
Purpose or tradeoff |
| Adapter |
Application/main.m:1 |
An adapter translates platform view callbacks or Objective-C objects into C++/metal-cpp calls. |
| Backend isolation |
Application/AAPLOpenGLViewController.m:55 |
Makes the sample’s separate Metal and OpenGL renderers an explicit, reviewable boundary. |
| Shared resource boundary |
Renderer/Metal/AAPLShaders.metal:22 |
Makes the sample’s separate Metal and OpenGL renderers an explicit, reviewable boundary. |
Naming conventions
- Role suffixes make ownership visible:
AAPLMetalViewController, AAPLOpenGLViewController, AAPLMetalRenderer, AAPLOpenGLRenderer, AAPLOpenGLView, AAPLAppDelegate, WindowSceneDelegate.
- Method names describe setup or encoding actions:
initWithDevice, useInteropTextureAsBaseMap, useTextureFromFileAsBaseMap, resize, updateState, drawToTexture, drawToMTKView.
- Shader entry points use stage/operation names:
vertexShader, fragmentShader.
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
AAPLMetalViewController focused on composition; AAPLMetalRenderer is the owner of separate Metal and OpenGL renderers.
- Treat shared-view interoperability and presentation as a separate execution/compilation boundary with explicit resource and data-layout contracts.
- The verified ownership edge is
AAPLOpenGLViewController → _openGLRenderer; 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 |
Application/AAPLOpenGLMetalInteropTexture.m |
AAPLOpenGLMetalInteropTexture |
Application/AAPLOpenGLViewController.m |
AAPLOpenGLView, AAPLOpenGLViewController |
Renderer/Metal/AAPLShaders.metal |
entry point or feature implementation |
Application/main.m |
entry point or feature implementation |
Renderer/Metal/AAPLMetalRenderer.m |
AAPLMetalRenderer |
Application/WindowSceneDelegate.m |
WindowSceneDelegate |
Renderer/Metal/AAPLShaderTypes.h |
entry point or feature implementation |
Application/AAPLAppDelegate.h |
AAPLAppDelegate |
Application/AAPLOpenGLViewController.h |
AAPLOpenGLView, AAPLOpenGLViewController |