CNA-BUG-246: docs/graphics-resource-lifetime.md says existing XNA resources hold a unique_ptr renderer and names a non-existent ITexture2DRenderer; Texture2D, Texture3D and TextureCube hold shared_ptr renderers and Texture2D's public copies share one
Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.
The document's Ownership Model gives unique_ptr renderer ownership for existing XNA resources, a list its scope sentence extends to Texture2D and RenderTarget2D, and knows only one kind of sharing: an internal record on non-copyable modern resources. Texture2D, Texture3D and TextureCube hold shared_ptr renderers, and Texture2D's public defaulted copies share the renderer and CPU shadow.
- Identifier
CNA-BUG-246- Category
- Bug
- Subsystem
- Documentation & release tooling
- Status
- Open
- Verified against
- CNA
009d40f5(009d40f5dd085c4e674d3479675fac84b12b3e0a) - Severity
- Low (a triage suggestion, not a project priority)
- Evidence basis
- Source-verified: read at TARGET, not executed
- Tests touching this area
- Yes: see Current tests
- Affected contract
- docs/graphics-resource-lifetime.md section 1 (Ownership Model) against Microsoft::Xna::Framework::Graphics::Texture2D (copy constructor, copy assignment, GetRendererWeak, GetCpuPixelsWeak), Texture3D and TextureCube
Expected behaviour
The lifetime document describes the ownership that the resource classes implement, so that a maintainer reasoning about disposal, copies and native-handle retention starts from the right model.
Actual behaviour at TARGET
graphics-resource-lifetime.md section 1 says existing XNA resources hold a std::unique_ptr<IXxxRenderer> (for example IVertexBufferRenderer or ITexture2DRenderer) and that a modern resource such as Texture2DArray may instead own an internal shared record that never reaches the public API; its scope sentence names Texture2D and RenderTarget2D among the covered types. At TARGET no type named ITexture2DRenderer exists under modules/ (the real interface is ITextureRenderer). Texture2D.hpp holds std::shared_ptr<ITextureRenderer> renderer_, a shared cpuPixels_ vector and shared extraMipLevels_; its public CNAEXT copy constructor and copy assignment are defaulted and documented as sharing 'the underlying texture resource', and GetRendererWeak()/GetCpuPixelsWeak() hand out weak references. Texture3D.hpp and TextureCube.hpp hold std::shared_ptr renderers too. Of the five resource headers read, only VertexBuffer.hpp and IndexBuffer.hpp follow the unique-ownership rule, which is the shape section 5's move example uses. The document has no account of the texture family's public value-copy sharing.
Source locations
docs/graphics-resource-lifetime.md— section 1, Ownership Modelmodules/graphics/include/Microsoft/Xna/Framework/Graphics/Texture2D.hpp— renderer_, cpuPixels_, extraMipLevels_, defaulted copy operations, GetRendererWeak, GetCpuPixelsWeakmodules/graphics/include/Microsoft/Xna/Framework/Graphics/Texture3D.hpp— renderer_ is a shared_ptrmodules/graphics/include/Microsoft/Xna/Framework/Graphics/TextureCube.hpp— renderer_ is a shared_ptrmodules/graphics/include/Microsoft/Xna/Framework/Graphics/VertexBuffer.hpp— renderer_ is a unique_ptrmodules/graphics/include/Microsoft/Xna/Framework/Graphics/IndexBuffer.hpp— renderer_ is a unique_ptrmodules/graphics/include/CNA/Internal/Renderers/Common/IGraphicsRenderer.hpp— ITextureRenderer, the real texture renderer interface
Evidence
Checked by reading at 009d40f5; not executed. Read the document's section 1 and 5 and the member declarations and Doxygen of the five resource headers; searched modules/ for ITexture2DRenderer (no match). The document last changed in 1321ca346 and is identical at TARGET; another sentence of the same document is tracked separately.
Independent re-verification: Checked by reading at 009d40f5; not executed. Read the document's sections 1, 2 and 5, the member declarations and Doxygen of the five resource headers and Texture2DArray.hpp; searched modules/ for ITexture2DRenderer (only the document names it). Correction to the earlier wording: the sentence that sharing never reaches the public API is about the internal record of modern resources such as Texture2DArray, whose copy and move are deleted, and is true for that class; the defect is that the two-way model has no place for the texture family's shared_ptr holders and public copies.
Focused reproduction
No focused reproduction is known. Nothing has been invented here; the evidence above is what exists.
Current tests
Texture2DTests.cpp checks that copies preserve width, height and format; nothing checks the document.
Regression test
Documentation fix: state per resource family which holder is used (shared for the texture family, with value copies sharing the renderer and CPU shadow; unique for buffers) and replace ITexture2DRenderer with ITextureRenderer.
Blast radius
Maintainers and extension authors who reason about texture disposal, copying or native-handle retention from this document; no runtime behaviour is affected.
Workaround
Read the ownership from the headers: textures are shared value wrappers; buffers own their renderer uniquely.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- 3D rendering guide
- Deep dives
- Texture data transfer: Texture2D shape
- Known issues
- Bug index