From 4f50bedde0cda1ffc9b24c7423473462030b9ea7 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sat, 31 Oct 2026 19:58:19 +0800 Subject: [PATCH] [Docs, Chore] (docs, tools, MobileGL, scripts, CONTRIBUTING.md, .gitignore): translate the documentation and use US spelling --- .gitignore | 2 +- CONTRIBUTING.md | 14 +- MobileGL/BackendCaps.h | 12 +- MobileGL/Config.h | 18 +- MobileGL/ConfigLoader.cpp | 8 +- MobileGL/MG_Backend/BackendFunctions.h | 2 +- MobileGL/MG_Backend/BackendRoles.h | 2 +- .../DirectGLES/BackendObject_DirectGLES.cpp | 24 +- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 2 +- MobileGL/MG_Backend/DirectGLES/DirectGLES.h | 10 +- .../MG_Backend/DirectGLES/DirectGLESBind.cpp | 6 +- .../MG_Backend/DirectGLES/DirectGLESBlit.cpp | 30 +- .../DirectGLES/DirectGLESBuffers.cpp | 6 +- .../DirectGLES/DirectGLESContext.cpp | 6 +- .../MG_Backend/DirectGLES/DirectGLESCopy.cpp | 8 +- .../MG_Backend/DirectGLES/DirectGLESDraw.cpp | 14 +- .../DirectGLES/DirectGLESInternal.h | 8 +- .../DirectGLES/DirectGLESReadback.cpp | 36 +- .../DirectGLES/DirectGLESSharedImage.cpp | 4 +- .../MG_Backend/DirectGLES/DirectGLESState.cpp | 12 +- .../MG_Backend/DirectGLES/DirectGLESSync.cpp | 2 +- .../DirectGLES/DirectGLESTextures.cpp | 8 +- MobileGL/MG_Backend/DirectGLES/Managers.cpp | 10 +- MobileGL/MG_Backend/DirectGLES/Managers.h | 40 +-- .../MG_Backend/DirectGLES/ManagersBuffers.cpp | 13 +- .../DirectGLES/ManagersFramebuffers.cpp | 26 +- .../MG_Backend/DirectGLES/ManagersInternal.h | 4 +- .../DirectGLES/ManagersPrograms.cpp | 38 +- .../DirectGLES/ManagersSamplers.cpp | 4 +- .../DirectGLES/ManagersTextureSync.cpp | 10 +- .../DirectGLES/ManagersTextures.cpp | 18 +- .../DirectGLES/ManagersVertexArrays.cpp | 6 +- MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp | 10 +- .../DirectGLES/NarrowIntegerSeeds.cpp | 2 +- MobileGL/MG_Backend/DirectGLES/SlotTables.h | 8 +- MobileGL/MG_Backend/DirectGLES/Utils.cpp | 14 +- MobileGL/MG_Backend/DirectGLES/Utils.h | 22 +- .../BackendObject_DirectVulkan.cpp | 6 +- .../MG_Backend/DirectVulkan/DirectVulkan.cpp | 4 +- .../MG_Backend/DirectVulkan/MagmaSession.h | 2 +- .../DirectVulkan/Renderer/FrameContext.cpp | 2 +- .../Renderer/MagmaProgramSource.h | 2 +- .../DirectVulkan/Renderer/ProgramFactory.cpp | 24 +- .../DirectVulkan/Renderer/ProgramFactory.h | 4 +- .../DirectVulkan/Renderer/SwapchainObject.h | 4 +- .../DirectVulkan/Renderer/VkBufferManager.cpp | 6 +- .../DirectVulkan/Renderer/VkBufferManager.h | 2 +- .../DirectVulkan/Renderer/VkClearManager.cpp | 2 +- .../DirectVulkan/Renderer/VkClearManager.h | 4 +- .../Renderer/VkRenderPassManager.cpp | 2 +- .../Renderer/VkRenderPassManager.h | 2 +- .../Renderer/VkSamplerManager.cpp | 16 +- .../DirectVulkan/Renderer/VkSamplerManager.h | 6 +- .../Renderer/VkTextureManager.cpp | 6 +- .../DirectVulkan/Renderer/VkTextureManager.h | 6 +- .../DirectVulkan/Renderer/VulkanRenderer.h | 14 +- .../Renderer/VulkanRendererCopy.cpp | 8 +- .../Renderer/VulkanRendererDevice.cpp | 6 +- .../Renderer/VulkanRendererDraw.cpp | 4 +- .../Renderer/VulkanRendererPipeline.cpp | 22 +- .../Renderer/VulkanRendererPresent.cpp | 2 +- .../Renderer/VulkanRendererSubmit.cpp | 4 +- .../DirectVulkan/Renderer/WireColorBlit.cpp | 4 +- .../Renderer/WireColorBlitFilter.h | 16 +- .../Renderer/WireCopySliceProbe.cpp | 2 +- .../DirectVulkan/Renderer/WireDepthMipmap.cpp | 4 +- .../Renderer/WireDepthResolveProbe.cpp | 4 +- .../DirectVulkan/Renderer/WireDraw.cpp | 6 +- .../DirectVulkan/Renderer/WireE5RawCopy.h | 4 +- .../DirectVulkan/Renderer/WireFramebuffer.cpp | 36 +- .../Renderer/WireMultisampleResolve.cpp | 4 +- .../Renderer/WirePlaceholderKey.h | 2 +- .../DirectVulkan/Renderer/WireYuvImage.cpp | 6 +- MobileGL/MG_Backend/Init.cpp | 2 +- MobileGL/MG_Backend/MGPipe/PipeInputs.cpp | 6 +- MobileGL/MG_Backend/MGPipe/PipeInputs.h | 8 +- MobileGL/MG_Backend/Record/RecordVerbSink.cpp | 6 +- MobileGL/MG_Backend/Record/StagedShadow.h | 4 +- .../MG_Backend/Record/StagedTextureStore.h | 4 +- MobileGL/MG_Backend/SharedImageTypes.h | 4 +- MobileGL/MG_Benchmark/Driver/DriverBench.c | 2 +- .../MG_Benchmark/Driver/DriverBenchCases.inc | 2 +- .../ShaderCache/TranslationCacheBench.cpp | 4 +- .../Transpile/TranspileProfile.cpp | 4 +- MobileGL/MG_Gbm/MobileGLGbm.cpp | 4 +- .../MG_Impl/EGLImpl/EGLPlatformExtensions.h | 2 +- MobileGL/MG_Impl/EGLImpl/WaylandWindow.h | 2 +- MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp | 2 +- MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.cpp | 2 +- MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.h | 2 +- .../MG_Impl/GLImpl/Drawing/GL_Drawing.cpp | 2 +- .../GLImpl/Framebuffer/GL_Framebuffer.cpp | 24 +- .../MG_Impl/GLImpl/Framebuffer/Validators.cpp | 2 +- .../MG_Impl/GLImpl/Framebuffer/Validators.h | 2 +- MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp | 6 +- .../MG_Impl/GLImpl/Program/GL_Program.cpp | 8 +- .../GLImpl/RenderState/GL_RenderState.cpp | 2 +- .../MG_Impl/GLImpl/Sampler/GL_Sampler.cpp | 6 +- MobileGL/MG_Impl/GLImpl/Sync/GL_Sync.cpp | 2 +- .../MG_Impl/GLImpl/Texture/GL_Texture.cpp | 32 +- MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h | 2 +- .../MG_Impl/GLImpl/Texture/Validators.cpp | 8 +- .../MG_Impl/GLImpl/VertexArray/Validators.cpp | 2 +- MobileGL/MG_Impl/GLXImpl/GLXImpl.cpp | 2 +- MobileGL/MG_Impl/GLXImpl/X11PresentXcb.h | 2 +- MobileGL/MG_Impl/Pipe/CsoCache.h | 2 +- MobileGL/MG_Impl/Pipe/FramebufferEmit.h | 16 +- MobileGL/MG_Impl/Pipe/ImageEmit.h | 2 +- MobileGL/MG_Impl/Pipe/PipeFill.cpp | 30 +- MobileGL/MG_Impl/Pipe/ProgramEmit.h | 2 +- MobileGL/MG_Impl/Pipe/ResourceTracker.h | 2 +- MobileGL/MG_Impl/Pipe/SamplerEmit.h | 4 +- MobileGL/MG_Impl/Pipe/SlotAllocator.h | 2 +- MobileGL/MG_Impl/Pipe/TextureEmit.h | 6 +- MobileGL/MG_Impl/Pipe/Tracker.h | 4 +- .../MG_Impl/Pipe/Verb/TextureReadbackEmit.inc | 2 +- MobileGL/MG_Impl/Pipe/Verb/VerbPort.cpp | 4 +- MobileGL/MG_Impl/Pipe/VertexInputEmit.h | 2 +- MobileGL/MG_Impl/SharedImageApi.h | 4 +- MobileGL/MG_IntegrationTest/CMakeLists.txt | 2 +- .../Harness/BackendCapsPeek.h | 2 +- .../MG_IntegrationTest/Harness/HeadlessGL.cpp | 4 +- .../MG_IntegrationTest/Harness/HeadlessGL.h | 12 +- .../MG_IntegrationTest/Harness/PipeSlotPeek.h | 2 +- .../Harness/PipeStatsWindow.h | 2 +- .../Harness/ScenarioFixture.h | 2 +- .../MG_IntegrationTest/Harness/SplitLane.h | 4 +- .../Harness/SplitRuntimePeek.h | 2 +- .../Harness/WireLedgerChecks.h | 6 +- .../Harness/split_log_paths.py | 2 +- .../Harness/test_split_log_paths.py | 2 +- MobileGL/MG_IntegrationTest/P8Coverage.cmake | 2 +- .../Scenarios/AdvertisedLimitsScenario.cpp | 2 +- .../Scenarios/AsyncCompileScenario.cpp | 2 +- .../Scenarios/AtomicCounterScenario.cpp | 4 +- .../Scenarios/BandedReadbackScenario.cpp | 2 +- .../Scenarios/ClearOrderScenario.cpp | 8 +- .../Scenarios/ClearThenReadPixelsScenario.cpp | 6 +- .../Scenarios/ClientVertexArrayScenario.cpp | 6 +- .../Scenarios/ClipControlScenario.cpp | 2 +- .../Scenarios/ClipDistanceScenario.cpp | 6 +- .../Scenarios/CopyImageLayeredScenario.cpp | 2 +- .../Scenarios/CopyImagePacked16Scenario.cpp | 4 +- .../CopyImageStoreReadbackScenario.cpp | 6 +- .../Scenarios/CrossFrameBufferScenario.cpp | 28 +- .../CsoContentAddressingScenario.cpp | 4 +- .../Scenarios/CtWireScenario.cpp | 4 +- .../DefaultFramebufferAcrossSwapScenario.cpp | 6 +- .../Scenarios/DeletedBoundBufferScenario.cpp | 2 +- ...StencilReadbackAttachmentShapeScenario.cpp | 14 +- .../DepthStencilReadbackMatrixScenario.cpp | 30 +- .../DepthStencilReadbackScenario.cpp | 10 +- .../DescriptorPoolGrowthScenario.cpp | 2 +- .../Scenarios/DoublePrecisionScenario.cpp | 4 +- .../Scenarios/DrawParametersScenario.cpp | 2 +- .../DsaUpdateKeepsTheBoundUnitScenario.cpp | 2 +- .../Scenarios/DualBlockScenario.cpp | 2 +- .../Scenarios/DualSourceBlendScenario.cpp | 4 +- .../Scenarios/F1WireScenario.cpp | 54 +-- .../Scenarios/FormatlessImageBakeScenario.cpp | 2 +- .../FragmentOutputArrayIndexScenario.cpp | 2 +- .../GenerateMipmapServerScenario.cpp | 8 +- .../Scenarios/GeometryDrawModeScenario.cpp | 4 +- .../Scenarios/Glsl420DeclarationScenario.cpp | 8 +- .../Scenarios/GpuWrittenDrawInputScenario.cpp | 4 +- .../Scenarios/GuiBatchScenario.cpp | 8 +- .../Scenarios/HandleRecycleScenario.cpp | 50 +-- .../Scenarios/ImageBindableRemintScenario.cpp | 4 +- .../Scenarios/ImageLoadStoreSsoScenario.cpp | 4 +- .../ImageSizeAfterRespecScenario.cpp | 6 +- .../Scenarios/ImageTargetKindScenario.cpp | 6 +- .../Scenarios/InPassClearScenario.cpp | 6 +- .../Scenarios/IntegerBorderColorScenario.cpp | 22 +- .../Scenarios/InvalidImageUnitScenario.cpp | 2 +- .../IoBlockNameCollisionScenario.cpp | 10 +- .../Scenarios/LargeArenaAdoptionScenario.cpp | 2 +- .../LayeredAttachmentBarrierScenario.cpp | 14 +- .../LayeredAttachmentShapeScenario.cpp | 71 ++-- .../Scenarios/MagmaRunAheadScenario.cpp | 2 +- .../Scenarios/MagmaVertexLayoutScenario.cpp | 6 +- .../Scenarios/MagmaWireReclaimScenario.cpp | 12 +- .../Scenarios/MultiDrawScenario.cpp | 4 +- .../ObjectSubsystemControlScenario.cpp | 24 +- .../Scenarios/OrientationScenario.cpp | 20 +- .../OversizedRecordingSplitScenario.cpp | 8 +- .../Scenarios/P4aFinalFixScenario.cpp | 6 +- .../Scenarios/P4aSeamAuditScenario.cpp | 12 +- .../Scenarios/PackedWordReadbackScenario.cpp | 6 +- .../PartialUploadOverGpuContentScenario.cpp | 2 +- .../PersistentCoherentMapScenario.cpp | 4 +- .../Scenarios/PipeVerifyArmingScenario.cpp | 4 +- .../Scenarios/PipelineFailureScenario.cpp | 2 +- .../Scenarios/PixelStoreSweepScenario.cpp | 6 +- .../Scenarios/PoisonOmissionScenario.cpp | 6 +- .../Scenarios/PostLinkAttachScenario.cpp | 12 +- .../Scenarios/PrimitiveRestartScenario.cpp | 8 +- .../Scenarios/ProgramPipelineScenario.cpp | 18 +- .../Scenarios/RelinkStageSetScenario.cpp | 12 +- .../RenderbufferBlendFormatScenario.cpp | 14 +- .../Scenarios/ResidentIndexScenario.cpp | 2 +- .../ResourceSubsystemControlScenario.cpp | 8 +- .../Scenarios/SampleMaskScopeScenario.cpp | 2 +- .../Scenarios/SampleVariablesScenario.cpp | 2 +- .../Scenarios/SampledSetStalenessScenario.cpp | 10 +- .../Scenarios/ScenarioIsolationScenario.cpp | 4 +- .../Scenarios/SnormAttachmentScenario.cpp | 18 +- .../Scenarios/SpirvShaderBinaryScenario.cpp | 8 +- .../Scenarios/StorageBufferRegrowScenario.cpp | 4 +- .../TessellationXfbCaptureScenario.cpp | 6 +- ...xtureParamsWithoutASamplerViewScenario.cpp | 25 +- .../Scenarios/TextureUploadShapeScenario.cpp | 2 +- .../Scenarios/TextureViewAliasScenario.cpp | 10 +- .../Scenarios/TextureViewScenario.cpp | 26 +- .../ThreeChannelAttachmentScenario.cpp | 16 +- .../Scenarios/TriangleScenario.cpp | 8 +- .../UnboundImageDescriptorScenario.cpp | 4 +- .../Scenarios/UnboundUniformBlockScenario.cpp | 8 +- .../Scenarios/UniformInitializerScenario.cpp | 2 +- .../Scenarios/UnlocatedIoBlockScenario.cpp | 8 +- .../Scenarios/UploadOrderScenario.cpp | 2 +- .../Scenarios/VaoShadowScenario.cpp | 2 +- .../Scenarios/VertexAttribBindingScenario.cpp | 2 +- .../Scenarios/ViewportArrayScenario.cpp | 20 +- .../Scenarios/WindowPassGateScenario.cpp | 6 +- .../Scenarios/WireMipShapeScenario.cpp | 4 +- .../Scenarios/WriteRenameScenario.cpp | 4 +- .../XfbAfterClipDistanceScenario.cpp | 6 +- .../XfbCaptureBufferReuseScenario.cpp | 2 +- .../Scenarios/XfbPrimitiveQueryScenario.cpp | 2 +- .../Scenarios/XfbRepeatedCaptureScenario.cpp | 2 +- MobileGL/MG_Pipe/DirtySurface.def | 2 +- MobileGL/MG_Pipe/FatalFamilies.def | 2 +- MobileGL/MG_Pipe/MGPipe.h | 8 +- MobileGL/MG_Pipe/MGPipeHandles.h | 4 +- MobileGL/MG_Pipe/MGPipeRenderStateSpans.cpp | 2 +- MobileGL/MG_Pipe/MGPipeTypes.h | 30 +- MobileGL/MG_Pipe/MGPipeValueTypes.h | 14 +- MobileGL/MG_Pipe/PipeApply.cpp | 28 +- MobileGL/MG_Pipe/PipeApply.h | 30 +- MobileGL/MG_Pipe/PipeCalls.def | 4 +- MobileGL/MG_Pipe/PipeFields.def | 4 +- MobileGL/MG_Pipe/PipeMutation.h | 4 +- MobileGL/MG_Pipe/PipeRoute.cpp | 8 +- MobileGL/MG_Pipe/PipeRoute.h | 8 +- MobileGL/MG_Pipe/PipeSessionFail.h | 6 +- MobileGL/MG_Pipe/generated/PipeTables.inc | 6 +- MobileGL/MG_Pipe/generated/PipeWire.inc | 18 +- MobileGL/MG_Pipe/generated/PipeWireLayout.inc | 2 +- MobileGL/MG_Remote/CapsCodec.cpp | 2 +- .../MG_Remote/Client/BackendObject_Remote.cpp | 10 +- MobileGL/MG_Remote/Client/CapsMirror.cpp | 2 +- MobileGL/MG_Remote/Client/ClientSession.cpp | 18 +- MobileGL/MG_Remote/Client/ClientSession.h | 6 +- MobileGL/MG_Remote/Client/EmitTables.h | 4 +- MobileGL/MG_Remote/Client/GpuWritePending.cpp | 2 +- MobileGL/MG_Remote/Client/WireTables.cpp | 10 +- MobileGL/MG_Remote/FatalFunnel.h | 2 +- MobileGL/MG_Remote/Server/ApplyThreadPolicy.h | 2 +- MobileGL/MG_Remote/Server/PipeApplier.cpp | 6 +- MobileGL/MG_Remote/Server/ServerDisplay.cpp | 2 +- MobileGL/MG_Remote/Server/ServerDisplay.h | 2 +- MobileGL/MG_Remote/Server/ServerLoop.cpp | 16 +- MobileGL/MG_Remote/Server/ServerLoop.h | 6 +- MobileGL/MG_Remote/Server/ServerMain.cpp | 2 +- MobileGL/MG_Remote/Server/ServerSession.cpp | 2 +- .../MG_Remote/Server/SharedImageRegistry.cpp | 2 +- .../MG_Remote/Server/SharedImageRegistry.h | 8 +- MobileGL/MG_Remote/Server/SharedImageYuv.h | 4 +- MobileGL/MG_Remote/Transport/Doorbell.cpp | 2 +- MobileGL/MG_Remote/Transport/Doorbell.h | 2 +- MobileGL/MG_Remote/Transport/ILink.h | 6 +- MobileGL/MG_Remote/Transport/ITransport.h | 2 +- .../Transport/InProcessTransport.cpp | 2 +- MobileGL/MG_Remote/Transport/LogForward.cpp | 2 +- MobileGL/MG_Remote/Transport/LogForward.h | 2 +- MobileGL/MG_Remote/Transport/ReplySlot.h | 6 +- MobileGL/MG_Remote/Transport/Ring.cpp | 6 +- MobileGL/MG_Remote/Transport/Ring.h | 4 +- MobileGL/MG_Remote/Transport/SessionRings.h | 6 +- MobileGL/MG_Remote/Transport/ShmSegment.cpp | 4 +- .../MG_Remote/Transport/SocketTransport.h | 2 +- MobileGL/MG_Remote/Wire/PipeWireCodec.cpp | 22 +- MobileGL/MG_Remote/Wire/PipeWireCodec.h | 10 +- MobileGL/MG_State/EGLState/Core.h | 2 +- .../GLState/BufferState/BufferObject.cpp | 4 +- .../GLState/BufferState/BufferObject.h | 2 +- .../GLState/BufferState/BufferState.h | 2 +- .../BufferState/PersistentMapTracker.cpp | 20 +- .../BufferState/PersistentMapTracker.h | 6 +- .../GLState/BufferState/PipeResource.h | 2 +- MobileGL/MG_State/GLState/Core.cpp | 8 +- MobileGL/MG_State/GLState/Core.h | 4 +- .../FramebufferState/FramebufferObject.cpp | 2 +- .../GLState/ProgramState/ProgramArtifacts.h | 6 +- .../ProgramState/ProgramArtifactsCodec.h | 2 +- .../GLState/ProgramState/ProgramLinkTask.cpp | 24 +- .../GLState/ProgramState/ProgramLinkTask.h | 4 +- .../GLState/ProgramState/ProgramObject.cpp | 18 +- .../GLState/ProgramState/ProgramObject.h | 16 +- .../GLState/ProgramState/ProgramSpirvTask.cpp | 2 +- .../ProgramState/ShaderCompileAdoptionMap.cpp | 6 +- .../ProgramState/ShaderCompileAdoptionMap.h | 6 +- .../ProgramState/ShaderCompileTask.cpp | 2 +- .../GLState/ProgramState/ShaderCompileTask.h | 4 +- .../GLState/ProgramState/ShaderObject.cpp | 8 +- .../GLState/ProgramState/ShaderObject.h | 8 +- .../GLState/RenderState/RenderState.h | 4 +- .../GLState/SamplerState/SamplerObject.cpp | 4 +- .../GLState/TextureState/MipmapStorage.cpp | 2 +- .../GLState/TextureState/MipmapStorage.h | 2 +- .../GLState/TextureState/TextureObject.cpp | 4 +- .../Backend/BackendObjectEglStateTest.cpp | 4 +- .../Backend/DirectGLES/EsslShaderPassTest.cpp | 14 +- .../DirectGLES/NarrowIntegerEsslTest.cpp | 4 +- .../DirectGLES/ViewportIndexRoutingTest.cpp | 2 +- .../BackendLoader/BackendLoaderTest.cpp | 10 +- MobileGL/MG_Test/Buffer/BufferTest.cpp | 4 +- MobileGL/MG_Test/Buffer/SplitBufferTest.cpp | 4 +- .../MG_Test/Framebuffer/FramebufferTest.cpp | 16 +- .../MG_Test/Pipe/CompositeResolverTest.cpp | 2 +- MobileGL/MG_Test/Pipe/FieldOwnershipTest.cpp | 16 +- MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp | 48 +-- MobileGL/MG_Test/Pipe/ImageEmitTest.cpp | 4 +- MobileGL/MG_Test/Pipe/PipeCatalogueTest.cpp | 46 +-- MobileGL/MG_Test/Pipe/PipeInputsTest.cpp | 6 +- MobileGL/MG_Test/Pipe/ProgramEmitTest.cpp | 14 +- MobileGL/MG_Test/Pipe/RecorderGoldenTest.cpp | 6 +- .../MG_Test/Pipe/RenderStateSpansTest.cpp | 6 +- MobileGL/MG_Test/Pipe/ResourceEmitTest.cpp | 12 +- MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp | 12 +- .../MG_Test/Pipe/ShaderBufferEmitTest.cpp | 2 +- MobileGL/MG_Test/Pipe/TextureEmitTest.cpp | 6 +- MobileGL/MG_Test/Pipe/TrackerTest.cpp | 2 +- MobileGL/MG_Test/Pipe/VertexInputEmitTest.cpp | 2 +- .../Pipeline/PassthroughTessControlTest.cpp | 6 +- .../MG_Test/Pipeline/PipelineQuirkTest.cpp | 8 +- .../MG_Test/Program/AsyncSpirvPhaseTest.cpp | 10 +- .../MG_Test/Program/AsyncTeardownTest.cpp | 2 +- .../MG_Test/Program/OptimisticStatusTest.cpp | 2 +- .../Program/ParallelShaderCompileTest.cpp | 2 +- .../MG_Test/Program/ProgramInterfaceTest.cpp | 2 +- MobileGL/MG_Test/Program/ProgramTest.cpp | 30 +- MobileGL/MG_Test/Program/ProgramUtilTest.cpp | 16 +- .../Program/ShaderCompileAdoptionTest.cpp | 20 +- MobileGL/MG_Test/SanityTest.cpp | 12 +- .../MG_Test/SelfTest/DriverBugProbesTest.cpp | 8 +- .../PrimitivesGeneratedNoXfbProbeTest.cpp | 2 +- .../ClampMultisampleFetchTest.cpp | 8 +- .../ShaderTranspiler/DemoteFloat64Test.cpp | 2 +- ...ndNarrowIntegerVertexInputsRuntimeTest.cpp | 2 +- .../ExtendNarrowIntegerVertexInputsTest.cpp | 2 +- .../FixIterationRPSubgroupScratchTest.cpp | 2 +- .../FlattenFloat64StorageBlockTest.cpp | 4 +- .../ShaderTranspiler/GlslangCaptureTest.cpp | 12 +- .../StripIoBlockLocationsTest.cpp | 6 +- .../ShaderTranspiler/TranslationCacheTest.cpp | 12 +- .../UniquifyIoBlockNamesTest.cpp | 2 +- .../MG_Test/State/NegativeApiErrorsTest.cpp | 2 +- .../MG_Test/State/ObjectLifetimeIdTest.cpp | 2 +- MobileGL/MG_Test/State/RenderStateTest.cpp | 2 +- .../State/TransformFeedbackLifetimeIdTest.cpp | 2 +- MobileGL/MG_Test/Texture/TextureTest.cpp | 50 +-- MobileGL/MG_Test/Util/DamageTest.cpp | 2 +- MobileGL/MG_Test/Util/JobNodeTest.cpp | 4 +- MobileGL/MG_Test/Util/LogLevelTest.cpp | 2 +- .../MG_Test/VertexArray/VertexArrayTest.cpp | 2 +- .../VertexAttribBindingStateTest.cpp | 2 +- MobileGL/MG_Test/Wire/ClientRecoveryTest.cpp | 2 +- .../MG_Test/Wire/ConcurrentContextsTest.cpp | 8 +- .../MG_Test/Wire/EventForfeitPeerTest.cpp | 4 +- MobileGL/MG_Test/Wire/FatalFamilyTest.cpp | 2 +- MobileGL/MG_Test/Wire/LogForwardTest.cpp | 2 +- MobileGL/MG_Test/Wire/MultiSessionTest.cpp | 22 +- MobileGL/MG_Test/Wire/P12ServerRig.h | 6 +- MobileGL/MG_Test/Wire/PeerLatchTest.cpp | 4 +- .../MG_Test/Wire/PersistentMapFaultTest.cpp | 8 +- MobileGL/MG_Test/Wire/PipeWireCodecTest.cpp | 24 +- .../MG_Test/Wire/RemoteClientControls.inc | 4 +- MobileGL/MG_Test/Wire/RemoteClientTest.cpp | 14 +- MobileGL/MG_Test/Wire/RingTest.cpp | 8 +- .../MG_Test/Wire/ServerContextLiveTest.cpp | 2 +- MobileGL/MG_Test/Wire/ServerLoopTest.cpp | 18 +- .../MG_Test/Wire/ServerOwnedSurfaceTest.cpp | 2 +- MobileGL/MG_Test/Wire/ServerSpawnTest.cpp | 4 +- .../MG_Test/Wire/SessionHandshakeTest.cpp | 4 +- MobileGL/MG_Test/Wire/SessionTest.cpp | 4 +- MobileGL/MG_Test/Wire/SharedImageTest.cpp | 10 +- .../MG_Test/Wire/StagedTextureStoreTest.cpp | 6 +- MobileGL/MG_Test/Wire/StreamLinkTest.cpp | 2 +- MobileGL/MG_Test/Wire/TwinOwnershipTest.cpp | 2 +- MobileGL/MG_Util/Async/JobNode.cpp | 2 +- MobileGL/MG_Util/Async/JobNode.h | 14 +- MobileGL/MG_Util/Async/ShaderCompilePool.cpp | 8 +- MobileGL/MG_Util/Async/ShaderCompilePool.h | 4 +- .../MG_Util/BackendLoaders/OpenGL/Loader.cpp | 10 +- .../MG_Util/BackendLoaders/OpenGL/Loader.h | 12 +- .../MG_Util/BackendLoaders/Vulkan/Loader.cpp | 2 +- .../MG_Util/BackendLoaders/Vulkan/Loader.h | 4 +- .../GLToMG/TextureEnumConverter.cpp | 6 +- .../MGToVk/TextureEnumConverter.cpp | 2 +- MobileGL/MG_Util/Debug/Log.h | 4 +- MobileGL/MG_Util/Math/FixedPointConversion.h | 4 +- MobileGL/MG_Util/Metrics/PipeStats.cpp | 2 +- MobileGL/MG_Util/SelfTest/DriverBugProbes.cpp | 32 +- MobileGL/MG_Util/SelfTest/DriverBugProbes.h | 16 +- MobileGL/MG_Util/SelfTest/DriverPost.cpp | 52 +-- MobileGL/MG_Util/SelfTest/DriverPost.h | 2 +- .../SelfTest/PrimitivesGeneratedNoXfbProbe.h | 4 +- .../ShaderTranspiler/ShaderCompiler.cpp | 2 +- .../MG_Util/ShaderTranspiler/ShaderCompiler.h | 2 +- .../ShaderSourceProcessor.cpp | 14 +- .../SpirvPasses/ClampMultisampleFetchPass.cpp | 6 +- .../SpirvPasses/ClampMultisampleFetchPass.h | 10 +- .../SpirvPasses/DeriveNumSubgroupsPass.cpp | 2 +- .../FixIterationRPSubgroupScratchPass.cpp | 2 +- .../FlattenAtomicCounterBlockPass.cpp | 2 +- .../FlattenFloat64StorageBlockPass.cpp | 6 +- .../FlattenXfbInterfaceBlocksPass.cpp | 2 +- .../SpirvPasses/Lower1DSampledImagesPass.cpp | 2 +- .../SpirvPasses/Lower1DSampledImagesPass.h | 2 +- .../LowerPixelCenterIntegerPass.cpp | 2 +- .../SpirvPasses/LowerPixelCenterIntegerPass.h | 2 +- .../SpirvPasses/LowerViewportIndexPass.h | 2 +- .../SpirvPasses/NarrowIntegerRuntimeWidths.h | 2 +- .../SpirvPasses/RetainGeometryOutputsPass.h | 2 +- .../SpirvPasses/StripIoBlockLocationsPass.cpp | 2 +- .../SpirvPasses/StripIoBlockLocationsPass.h | 4 +- .../SpirvPasses/UniquifyIoBlockNamesPass.h | 2 +- .../MG_Util/ShaderTranspiler/SpvcSession.h | 2 +- .../ShaderTranspiler/TranslationCache.cpp | 2 +- .../ShaderTranspiler/TranslationCache.h | 2 +- .../glslang/TMglGlslIoResolver.cpp | 2 +- MobileGL/MG_Util/Texture/EtcDecoder.cpp | 2 +- .../MG_Util/Texture/PixelStoreProcessor.cpp | 6 +- .../Texture/TextureFormatProcessor.cpp | 14 +- .../MG_Util/Texture/TextureFormatProcessor.h | 8 +- MobileGL/MG_Util/Types.h | 4 +- README.md | 4 +- docs/Disaggregated/ARCHITECTURE.md | 56 +-- docs/Disaggregated/CURRENT_STAGE_PROGRESS.md | 34 +- docs/Disaggregated/DEBTS.md | 92 ++--- docs/Disaggregated/MEASUREMENTS.md | 92 ++--- docs/Disaggregated/OPEN-QUESTIONS.md | 54 +-- docs/Disaggregated/README.md | 38 +- docs/Disaggregated/ROADMAP.md | 72 ++-- .../design/01-boundary-and-objects.md | 72 ++-- .../design/02-catalogue-and-records.md | 104 +++--- docs/Disaggregated/design/03-frontend.md | 156 ++++---- .../design/04-reverse-channel.md | 82 ++--- .../design/05-backend-and-server.md | 70 ++-- docs/Disaggregated/design/06-transport.md | 116 +++--- .../design/07-memory-readback-verification.md | 92 ++--- .../design/08-runtime-and-platform.md | 124 +++---- .../design/09-build-switches-counters.md | 130 +++---- docs/Disaggregated/design/10-phase-shapes.md | 24 +- .../design/11-state-ownership.md | 336 +++++++++--------- docs/Disaggregated/guide/build-and-run.md | 42 +-- docs/Disaggregated/guide/code-map.md | 22 +- docs/Disaggregated/guide/discipline.md | 26 +- docs/Disaggregated/guide/embedded-server.md | 82 +++-- docs/Disaggregated/guide/glossary.md | 40 +-- docs/Disaggregated/pwait/README.md | 6 +- docs/ci/ci-cleanup-log.md | 6 +- scripts/bake_internal_shaders.py | 2 +- scripts/check_include_closure.py | 10 +- scripts/ci/espryt_memo_purity.py | 4 +- scripts/ci/fatal_census.py | 2 +- scripts/ci/junit_tally.py | 4 +- scripts/ci/ph_latch_sites.py | 2 +- scripts/ci/protocol_revision_pin.py | 2 +- scripts/ci/spawn_lane_parity.py | 2 +- scripts/ci/split_coverage.py | 6 +- scripts/ci/tcp_lane_tools_test.py | 2 +- scripts/gen_pipe.py | 38 +- scripts/gen_pipe_dirty_surface.py | 28 +- scripts/gen_pipe_field_ownership.py | 10 +- scripts/p3a_untouched_regions.sh | 2 +- scripts/p3a_vertex_input_negative_control.sh | 4 +- scripts/p4a_descriptor_negative_control.sh | 6 +- scripts/p4a_untouched_regions.sh | 4 +- scripts/symbol_report.py | 12 +- tools/anland-mobilegl-plasma/SKILL.md | 4 +- .../reference/README.md | 9 +- .../handoff-legacy-mobilegl-unified.md | 6 +- .../reference/plan-ahb-dmabuf.md | 134 +++---- .../reference/runbook-plasma.md | 208 +++++------ .../scripts/chrome-recover.sh | 2 +- tools/anland-mobilegl-plasma/scripts/env.sh | 2 +- .../scripts/probes/yuvprobe.c | 4 +- tools/cts/README.md | 2 +- tools/cts/platform/tcuMobileGLPlatform.cpp | 2 +- tools/cts/probe/mgprobe.c | 2 +- tools/cts/scripts/cts_multi_report.py | 2 +- tools/cts/scripts/qpa_report.py | 2 +- tools/cts/scripts/run_cts_windows.py | 2 +- tools/cts/skills/gl-cts-on-mobilegl/SKILL.md | 2 +- .../skills/linux-gl-cts-on-mobilegl/SKILL.md | 2 +- tools/device_bench/bench.sh | 2 +- tools/device_bench/disagg/make_report.py | 2 +- tools/device_bench/p6/ab_session.py | 4 +- tools/device_bench/p6/render_ab.py | 4 +- tools/device_bench/session.sh | 2 +- tools/trace_replay/README.md | 6 +- tools/trace_replay/apitrace_fbo_dump.cpp | 4 +- tools/trace_replay/compare_actuals.py | 14 +- .../trace_replay/run_android_retrace_local.py | 12 +- tools/trace_replay/run_tcp_matrix.py | 2 +- tools/trace_replay/run_trace_case.cmake | 2 +- tools/trace_replay/test_compare_actuals.py | 4 +- tools/trace_replay/test_run_tcp_matrix.py | 4 +- tools/trace_replay/trace_replay_cli.cpp | 2 +- userguide/configuration.md | 2 +- 512 files changed, 2955 insertions(+), 2945 deletions(-) diff --git a/.gitignore b/.gitignore index 9c975231..56ec4bbd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ ################################################################################ -# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。 +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. ################################################################################ /build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a623a1b..24f809c4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,10 +16,10 @@ Commands below use `python3`. On Windows, run `python` instead. - **Subject only by default.** Add `- ` detail lines only when a detail really needs to be in the commit message. Leave one blank line after the subject. A detail that wraps continues on at most two lines indented by two spaces. No paragraphs and no trailers. - **Content** after `): ` is at most 72 characters of plain English in the imperative mood ("flush once per frame", not "flushes" or "flushed"). - **Type** is one or more of these, comma-separated (`[Fix, Test]`): - - `Feat`: new behaviour. - - `Fix`: corrects behaviour. - - `Perf`: faster or lighter, same behaviour. - - `Refactor`: restructures code, same behaviour. + - `Feat`: new behavior. + - `Fix`: corrects behavior. + - `Perf`: faster or lighter, same behavior. + - `Refactor`: restructures code, same behavior. - `Test`: tests only. - `Docs`: documentation and comments only. - `Build`: CMake, Gradle, toolchains. @@ -43,12 +43,12 @@ Example: ## Comments, strings and documentation -- Code, comments, log strings and commit messages are in English. Documentation may be in Chinese or English. +- Code, comments, log strings and commit messages are in English, and documentation may be in English. American spelling is preferred in all of them: documentation, comments, strings and identifiers (color, behavior, center, cancel, initialize, normalize, organize, analyze, license, defense, artifact, modeling, labeled, gray, honor, neighbor, catalog). - A comment states what the code does now and why, in a few lines. Rationale longer than about 15 lines belongs in a design document under `docs/`, with a one-line pointer in the code. - In code and comments, cite a symbol, file or section, never a line number: `ARCHITECTURE.md §1.3`, `VulkanRenderer::BeginFrame()`. Documents may keep `file:line` citations; the documentation citation check resolves them. - State the rule, not its history. No "previously" or "after review", and no planning ids in comments, strings, identifiers or file names. - Plain wording, without ALL-CAPS emphasis. -- In code and comments (C, C++, GLSL, CMake, shell, Python, YAML), do not name external projects such as Mesa, Zink or gallium; describe the technique instead. Naming the driver or hardware where a behaviour was observed (llvmpipe, ANGLE, Adreno, Mali) is fine, and so are file, package and extension names that contain these words (`50_mesa.json`, `GL_MESA_*`). +- In code and comments (C, C++, GLSL, CMake, shell, Python, YAML), do not name external projects such as Mesa, Zink or gallium; describe the technique instead. Naming the driver or hardware where a behavior was observed (llvmpipe, ANGLE, Adreno, Mali) is fine, and so are file, package and extension names that contain these words (`50_mesa.json`, `GL_MESA_*`). ## Code @@ -69,7 +69,7 @@ Example: 5. `MG_Test`, `MG_IntegrationTest` and `MG_Benchmark`. - Each backend is isolated. Files under `MG_Backend/DirectGLES/` or `MG_Backend/DirectVulkan/` are included only by the same backend, by the registry files directly in `MG_Backend/`, by the root `.cpp` files and by tests. - Platform-specific APIs stay behind an abstraction, never raw in logic code. -- A fix that restores intended behaviour ships unconditionally. Add a switch only for a real trade-off. +- A fix that restores intended behavior ships unconditionally. Add a switch only for a real trade-off. - A cache keyed on object identity uses a monotonic lifetime id, never a GL name or a pointer, because both are recycled. ## What goes in the repository diff --git a/MobileGL/BackendCaps.h b/MobileGL/BackendCaps.h index 5cac1154..1ec67a4e 100644 --- a/MobileGL/BackendCaps.h +++ b/MobileGL/BackendCaps.h @@ -173,7 +173,7 @@ namespace MobileGL { // vertex, tessellation control, tessellation evaluation and geometry at 0, and only // fragment (8 in GL, 4 in ES) and compute are guaranteed to have any. Every real ARM // GLES driver takes that allowance - a Mali-G925 reports 0 for all four - so a - // backend that cannot honour a graphics-stage storage block MUST report 0 here + // backend that cannot honor a graphics-stage storage block MUST report 0 here // rather than a hopeful number. Advertising a non-zero count the driver will refuse // does not make the block work; it only moves the failure from an honest // "unsupported" at query time to a backend link error the frontend never surfaces, @@ -242,7 +242,7 @@ namespace MobileGL { // GL_LAYER_PROVOKING_VERTEX / GL_VIEWPORT_INDEX_PROVOKING_VERTEX: which vertex of a // primitive supplies gl_Layer and gl_ViewportIndex. GL 4.6 table 23.65 makes // GL_UNDEFINED_VERTEX a legal answer for both, and it is the honest default - naming - // a convention is a statement about behaviour, so a backend that does not pin one + // a convention is a statement about behavior, so a backend that does not pin one // must not claim it does. DirectGLES fills the layer one from the ES 3.2 query and // the viewport one from GL_OES_viewport_array, and leaves UNDEFINED where the // capability is absent: without the viewport array extension only viewport 0 is ever @@ -271,7 +271,7 @@ namespace MobileGL { // same image and lets an implementation answer GL_FRAMEBUFFER_UNSUPPORTED // otherwise, which is what DirectVulkan (one combined attachment) and the // real ES drivers behind DirectGLES both do. Defaults to true so a backend - // that never sets it keeps the permissive behaviour. + // that never sets it keeps the permissive behavior. Bool SupportsDistinctDepthStencilAttachments = true; // Whether attaching a single layer of a 3D or array texture to a framebuffer actually // renders to that layer. DirectGLES hands the layer straight to @@ -312,9 +312,9 @@ namespace MobileGL { // profile") and the demotion there is mathematically mandatory, always. // Defaults to false so a backend that never sets it - and the no-backend case, which // is what standalone shader compiles and the unit tests run under - keeps the - // demotion, which is the behaviour that works everywhere. + // demotion, which is the behavior that works everywhere. Bool SupportsShaderFloat64 = false; - // Whether glVertexAttribLFormat / glVertexArrayAttribLFormat can be honoured, i.e. + // Whether glVertexAttribLFormat / glVertexArrayAttribLFormat can be honored, i.e. // whether a 64-bit vertex attribute can actually reach a shader unconverted. Detected, // never assumed: DirectVulkan needs VkPhysicalDeviceFeatures::shaderFloat64 (the // attribute travels as its 32-bit word pair, so no VK_FORMAT_R64* is required, but the @@ -382,7 +382,7 @@ namespace MobileGL { Bool FragmentShadingRateAttachmentWithDefaultFramebuffer = false; // What glGetFragmentShadingRatesEXT answers, one mask per sample count 1, 2, 4 .. 64 // (index = log2(samples)): bit (log2(w) << 2 | log2(h)) is set when that rate is - // honoured exactly at that sample count, i.e. gl_ShadingRateEXT reads it back + // honored exactly at that sample count, i.e. gl_ShadingRateEXT reads it back // unclamped. Zero masks mean no rate at all, which is what a sample count the device // cannot shade coarsely answers. Uint16 FragmentShadingRateMasks[7] = {}; diff --git a/MobileGL/Config.h b/MobileGL/Config.h index 01a87bb3..a0b378d4 100644 --- a/MobileGL/Config.h +++ b/MobileGL/Config.h @@ -164,7 +164,7 @@ namespace MobileGL::MG_Config { // surface's minimum (the frames-in-flight count still raises the request when it is // larger), clamped to the surface's maximum. With more images, the one the display has // just released is reused later, by when its release has usually signaled, so fewer - // frames start their window pass behind it. Each image costs a full-size colour buffer + // frames start their window pass behind it. Each image costs a full-size color buffer // plus the default framebuffer's depth/stencil buffer of the same size. Uint32 MagmaExtraSwapchainImages = 0; // MOBILEGL_MAGMA_MAX_DRAWS_PER_COMMAND_BUFFER: GL draws and dispatches Magma records into @@ -316,10 +316,10 @@ namespace MobileGL::MG_Config { // keeps the built-in default (MG_Util::Async::kAsyncShaderCompileDefault); falsy // forces every glCompileShader/glLinkProgram to run synchronously on the calling // thread AND withdraws GL_KHR_parallel_shader_compile, so the single switch reverts - // both the threading and the application-visible behaviour change. + // both the threading and the application-visible behavior change. QuirkOverride AsyncShaderCompile = QuirkOverride::Auto; // MOBILEGL_ASYNC_SHADER_COMPILE_THREADS: shader-compile worker count. 0 (unset) means - // auto, which is min(4, big cores); an explicit value is honoured as given. + // auto, which is min(4, big cores); an explicit value is honored as given. Uint32 AsyncShaderCompileThreads = 0; // MOBILEGL_DISABLE_SHADER_PREWARM: skip the glslang built-in table prewarm in // Initialize(), which moves ~20-100 ms of table building from the first shader compiles @@ -356,7 +356,7 @@ namespace MobileGL::MG_Config { // extension only ever gave the SHADER a compilable name: MobileGL has never // programmed a driver's INDEXED viewport state (SyncRenderState pushes index 0 // and nothing else), so on an extension-capable driver every index rasterized as - // index 0 exactly as it did without one. ForceOff returns to that behaviour - + // index 0 exactly as it did without one. ForceOff returns to that behavior - // the pre-emulation path, extension passthrough where it exists and // LowerViewportIndexPass' demote-to-a-plain-global where it does not - and is // the negative control the emulation is measured against. @@ -420,7 +420,7 @@ namespace MobileGL::MG_Config { // MOBILEGL_PIPE_PUSH: per-subsystem bitmask selecting which state the frontend // PUSHES over MGPipe instead of leaving the backend to pull it out of GLContext. // 0 - the only shipped value until the migration lands - is "pull everything", - // i.e. exactly today's behaviour, and is the default of a PULL build, where the + // i.e. exactly today's behavior, and is the default of a PULL build, where the // knob is meaningless anyway. A PUSH build defaults to every subsystem migrated so // far (MG_Pipe::kMGPipeSubsystemsMigratedAtP5e = 0x3fff), so MOBILEGL_PIPE_PUSH=0 in // the environment is the all-pull control and 0x1fff (kMGPipeSubsystemsMigratedAtP4a) @@ -447,7 +447,7 @@ namespace MobileGL::MG_Config { // (every MGPBufferRange::Res names a Buffer handle; P5e) // A dependency that is not met is REFUSED with one ERROR naming both bits and the // family runs its legacy arm; it is never half-run. - // 1<<63 NOT a subsystem, a BEHAVIOUR: turn OFF client-side content addressing of + // 1<<63 NOT a subsystem, a BEHAVIOR: turn OFF client-side content addressing of // CSOs, so every pipeline-version change mints a fresh CSO and the map is // never probed. The negative control the CSO design is measured against. // P13 W3b (ID-P13-3): bits 0-13 are FIXED ON. Their pre-handle arms are gone, so a mask @@ -489,7 +489,7 @@ namespace MobileGL::MG_Config { extern FeaturesTable Features; // --------------------------------------------------------------------------------- - // P5: the transport selector and the MOBILEGL_IPC_* family (ARCHITECTURE.md 16, 附 A) + // P5: the transport selector and the MOBILEGL_IPC_* family (ARCHITECTURE.md 16, appendix A) // --------------------------------------------------------------------------------- // // MOBILEGL_TRANSPORT = monolith | inproc | spawn | unix: | pipe:. @@ -573,7 +573,7 @@ namespace MobileGL::MG_Config { // The MOBILEGL_IPC_* family. A separate table rather than more FeaturesTable members, // for the G1 reason above and because every field here is meaningless without the - // transport: a build that cannot reach the MG_Remote code cannot honour one of them. + // transport: a build that cannot reach the MG_Remote code cannot honor one of them. // // P5 lands exactly the knobs P5's own packages read. A later phase's knob is added HERE, // through the integrator, and not invented at its call site - ARCHITECTURE.md appendix A holds @@ -753,7 +753,7 @@ namespace MobileGL::MG_Config { // own) and no SetWindowHandle, and take the surface's real geometry back from the server. // Meaningful only when this client talks to a remote server (MOBILEGL_TRANSPORT=spawn, the // fork or tcp:// control); under monolith / inproc it is parsed, logged as ignored, and - // changes nothing. `offscreen` (the default) is today's behaviour byte for byte. + // changes nothing. `offscreen` (the default) is today's behavior byte for byte. // Pbuffers stay pbuffers in both modes (D4: one mode per session, decided by the first). IpcSurface Surface = IpcSurface::Offscreen; }; diff --git a/MobileGL/ConfigLoader.cpp b/MobileGL/ConfigLoader.cpp index e10c3b91..2a1e91da 100644 --- a/MobileGL/ConfigLoader.cpp +++ b/MobileGL/ConfigLoader.cpp @@ -526,7 +526,7 @@ namespace MobileGL::MG_ConfigLoader { "ring to an apply thread"); return; } - // The three P6 forms. Recognised precisely, so the diagnostic can say "rejected" + // The three P6 forms. Recognized precisely, so the diagnostic can say "rejected" // rather than "unknown", which are different bugs on the operator's side. // P6 `sm`/`cp`: spawn is IMPLEMENTED. It launches a server process on a // rendezvous of its own and connects to it - the two processes are @@ -575,7 +575,7 @@ namespace MobileGL::MG_ConfigLoader { QueryEnvVariable("MOBILEGL_IPC_CONTROL", ipc.Control, "fork"); QueryEnvVariable("MOBILEGL_IPC_DATA", ipc.Data, "auto"); // Both ring floors are 1 MiB, not 0: a ring caps ONE record at half its size, and - // the catalogue's largest fixed payload (MGPFramebufferState, 304 bytes) plus a + // the catalog's largest fixed payload (MGPFramebufferState, 304 bytes) plus a // create_shader_state archive already needs far more than a toy ring. The ceilings // are sanity, not policy. ipc.RingMb = QueryEnvUint32("MOBILEGL_IPC_RING_MB", 8, 1, 1024); @@ -703,7 +703,7 @@ namespace MobileGL::MG_ConfigLoader { const Bool serverProcess = role != nullptr && std::strcmp(role, "server") == 0; if (ipc.Surface == MG_Config::IpcSurface::Server && !serverProcess && MG_Config::Transport != MG_Config::TransportMode::Spawn) { - // Said, not silently honoured: there is no remote server here to own a window. + // Said, not silently honored: there is no remote server here to own a window. MGLOG_W("Config: MOBILEGL_IPC_SURFACE=server is IGNORED - it asks a remote server " "(MOBILEGL_TRANSPORT=spawn, a fork or tcp:// control) to own the window surface, " "and this run has none. Window surfaces stay the client's own"); @@ -711,7 +711,7 @@ namespace MobileGL::MG_ConfigLoader { } if (MG_Config::Transport == MG_Config::TransportMode::Monolith) return; - // One line, on the arm where these numbers decide behaviour, because every one of + // One line, on the arm where these numbers decide behavior, because every one of // them is a number a bug report has to quote. // CREATE-WINDOW IS IN THIS LINE BECAUSE A RUN HAS TO SAY WHICH WINDOW IT USED. It was // missing while the value was a number nobody varied, and the moment it became one that diff --git a/MobileGL/MG_Backend/BackendFunctions.h b/MobileGL/MG_Backend/BackendFunctions.h index 4da95b4b..e4af4ccb 100644 --- a/MobileGL/MG_Backend/BackendFunctions.h +++ b/MobileGL/MG_Backend/BackendFunctions.h @@ -218,7 +218,7 @@ namespace MobileGL::MG_Backend { void (*BeginTransformFeedback)(GLenum primitiveMode); void (*EndTransformFeedback)(); // ARB_transform_feedback2. A backend that leaves these null keeps the single - // implicit capture span the frontend has always modelled; the frontend state + // implicit capture span the frontend has always modeled; the frontend state // (paused flag, per-object bindings) is tracked either way. void (*PauseTransformFeedback)(); void (*ResumeTransformFeedback)(); diff --git a/MobileGL/MG_Backend/BackendRoles.h b/MobileGL/MG_Backend/BackendRoles.h index 0a7ddc5e..34781431 100644 --- a/MobileGL/MG_Backend/BackendRoles.h +++ b/MobileGL/MG_Backend/BackendRoles.h @@ -146,7 +146,7 @@ namespace MobileGL::MG_Backend { return false; } // The same for a YUV fourcc, whose planes and hints `layout` gives. A YUV buffer the - // server did not export is taken too (its labelled CPU-copy fallback). + // server did not export is taken too (its labeled CPU-copy fallback). virtual Bool ImportSharedImagePlanes(int fd, Uint32 width, Uint32 height, Uint32 fourcc, const SharedImageImportLayout& layout, Uint64* outId) { (void)fd, (void)width, (void)height, (void)fourcc, (void)layout, (void)outId; diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp index 1e5c57e4..335049f9 100644 --- a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp @@ -266,7 +266,7 @@ namespace MobileGL::MG_Backend::DirectGLES { reasons.push_back("GL_DEPTH_COMPONENT32 native probe failed on OpenGL ES"); } if (options & PixelFormatNormalizeOptionBit::NoThreeChannelRenderTarget) { - reasons.push_back("no colour-renderable three-channel format on OpenGL ES"); + reasons.push_back("no color-renderable three-channel format on OpenGL ES"); } // A format is either 8- or 16-bit signed normalized, so at most one of the two ever // survives GetApplicablePixelFormatNormalizeOptions and the reason is not duplicated. @@ -369,7 +369,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // did - is not merely untidy: the two texture pnames are ES 3.1 state, so on an ES 3.0 // context the loader's rejected-probe clamp leaves them at 1 (see the multisample clamps // in the GLES loader) and the walk below would never run past one sample, recording {1} - // for EVERY colour format while GL_MAX_SAMPLES - ES 3.0 core, so genuinely answered - + // for EVERY color format while GL_MAX_SAMPLES - ES 3.0 core, so genuinely answered - // reports 4. Once the frontend validates against this list, that would reject every // multisample renderbuffer on such a context. Int GetGLESRenderbufferFormatMaxSamples(const MG_External::GLESCapabilities& capabilities, GLenum imageFormat) { @@ -707,7 +707,7 @@ namespace MobileGL::MG_Backend::DirectGLES { for (SizeT targetIndex = 0; targetIndex < kFormatCapabilityTextureTargetCount; ++targetIndex) { const auto target = static_cast(targetIndex); - // Colour-attachable targets need a colour-renderable fallback; the ordinary + // Color-attachable targets need a color-renderable fallback; the ordinary // fallback for a three-channel format is another three-channel one, which ES // accepts as a texture but never as an attachment. Recompute the fallback per // target so those formats get widened where the target demands it. @@ -814,7 +814,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const SizeT renderbufferTargetIndex = GetRenderbufferFormatCapabilityTargetIndex(); // A renderbuffer exists only to be attached, so it needs the same three-channel - // widening the colour-attachable texture targets get - and on the same terms: the + // widening the color-attachable texture targets get - and on the same terms: the // native storage is probed first, so a driver that renders to it keeps it. const Flags renderbufferOptions = TextureImpl::GetRenderTargetNormalizeOptions(capabilities, renderbufferTargetIndex); @@ -1053,7 +1053,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // built). UpdateAdvertisedCapabilityExtensions(m_GLESCapabilities); UpdateDynamicBackendParameters(); - // The colour-attachment cap the framebuffer family checks is known from here on. + // The color-attachment cap the framebuffer family checks is known from here on. DirectGLES::ResolveRecordArmFamilies(); PopulateFormatCapabilities(m_GLESFunctions, m_GLESCapabilities, MutableFormatCapabilities()); PrintFormatCapabilities(GetFormatCapabilities()); @@ -1540,7 +1540,7 @@ namespace MobileGL::MG_Backend::DirectGLES { E_GL_ARB_texture_rg, // GL_DEPTH_COMPONENT32F and GL_DEPTH32F_STENCIL8. E_GL_ARB_depth_buffer_float, - // The floating-point colour formats. Unlike the rest of this block this string DOES + // The floating-point color formats. Unlike the rest of this block this string DOES // gate CTS cases - KHR-GL4*.internalformat.texture2d.*{16f,32f} is keyed on it with no // core-version fallback, so eight cases per version list were NotSupported on formats // the backend has always had. @@ -1557,7 +1557,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // - multiple capture buffers per stream, gl_SkipComponents / gl_NextBuffer, the // indexed queries and glDrawTransformFeedbackStream (4.0); E_GL_ARB_transform_feedback3, - // - GL_RGB10_A2UI (3.3), GL_RGB9_E5 (3.0) and the integer colour formats (3.0); + // - GL_RGB10_A2UI (3.3), GL_RGB9_E5 (3.0) and the integer color formats (3.0); E_GL_ARB_texture_rgb10_a2ui, E_GL_EXT_texture_shared_exponent, E_GL_EXT_texture_integer, // - the eleven pipeline-statistics query targets (4.6). Accepted by glBeginQuery and // answered with GL_QUERY_COUNTER_BITS = 0, the spec's own "this counter is not @@ -1609,7 +1609,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // recorded trace can never cover: Iris and Sodium change their SUBMISSION SCHEDULE // the moment they see it - they enqueue whole pipeline batches and poll // GL_COMPLETION_STATUS_KHR instead of compiling one program at a time - so - // MOBILEGL_ASYNC_SHADER_COMPILE=0 has to withdraw the application-visible behaviour + // MOBILEGL_ASYNC_SHADER_COMPILE=0 has to withdraw the application-visible behavior // change as well as the threading, or the kill switch would only be half a switch. if (MG_Util::Async::AsyncShaderCompileEnabled()) { extensions.push_back(E_GL_KHR_parallel_shader_compile); @@ -1619,7 +1619,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // reaches this backend - so an application that simply uses doubles needs nothing // advertised. What the extension additionally promises is 64-bit PRECISION, which no // mobile GPU has and the narrowing cannot fake, so advertising it by default would - // make an application that checks the string take a path MobileGL cannot honour. + // make an application that checks the string take a path MobileGL cannot honor. if (MG_Config::Features.AdvertiseFp64) { extensions.push_back(E_GL_ARB_gpu_shader_fp64); } @@ -1650,7 +1650,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // DEPTH_STENCIL_TEXTURE_MODE = STENCIL_INDEX and through a view with DEPTH_COMPONENT, in // a single shading pass). A copy-based fallback satisfies neither half, and fails // silently; withholding the string and answering glTextureView with INVALID_OPERATION is - // the only behaviour that cannot be mistaken for success. + // the only behavior that cannot be mistaken for success. // // The host extension is necessary and NOT sufficient, which is why this second gate // exists. Adreno 830 has EXT_texture_view, and on it the whole functional half of @@ -1891,7 +1891,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // (MaxShaderStorageBufferBindings is assigned above, before the per-stage clamp reads it.) // This is the number glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE) hands the application, and - // on a host without buffer textures it is knowingly a floor MobileGL cannot honour rather + // on a host without buffer textures it is knowingly a floor MobileGL cannot honor rather // than a driver answer (m_GLESCapabilities.MaxTextureBufferSizeIsDriverReported says // which). Reporting 0 instead was considered and rejected: MobileGL advertises an OpenGL // 4.x context, where buffer textures are core and the limit has a spec minimum of 65536, @@ -2007,7 +2007,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // for gl_ViewportIndex on every driver without GL_OES_viewport_array - which is both test // devices. That is not a shortfall being hidden: without the extension only viewport 0 is // ever rasterized, so no vertex "selects" a viewport index and naming a convention would - // describe behaviour this backend does not implement. + // describe behavior this backend does not implement. m_dynamicParameters.LayerProvokingVertex = m_GLESCapabilities.LayerProvokingVertex; m_dynamicParameters.ViewportIndexProvokingVertex = m_GLESCapabilities.ViewportIndexProvokingVertex; // GL_EXT_fragment_shading_rate is a straight pass-through: the pipeline rate and the diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index e6f5a56c..71b75c0d 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -20,7 +20,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // deliberate and it is not this phase's to change: ARCHITECTURE.md assigns the two // backend-specific post-processings of the resolved sampler set - this one and Magma's // feedback-loop detection - to the server, acting ON the already-resolved set, and the - // ROADMAP puts "raw-depth-fetch sampler 原生化" in P3b/P4b beside Magma's placeholder + // ROADMAP puts "native raw-depth-fetch sampler" in P3b/P4b beside Magma's placeholder // textures. What P4a changes is only what the substitution READS: the resolved view's // format answers IsDepthFormatInternalFormat and the sampler CSO record's parameters // answer compareMode / minFilter / mipmapMode / magFilter. diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.h b/MobileGL/MG_Backend/DirectGLES/DirectGLES.h index c4f42c5d..7de760ea 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.h +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.h @@ -187,7 +187,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // glTexBuffer / glTexBufferRange through whichever spelling this driver's buffer-texture // support actually ships: the unsuffixed names are ES 3.2 core, while an EXT/OES driver // exports glTexBuffer{,Range}EXT / OES. Callers must have checked - // AreBufferTexturesSupported() first. CallTexBufferRange reports whether it could honour + // AreBufferTexturesSupported() first. CallTexBufferRange reports whether it could honor // the range - no tier is required to expose the range form, and the whole-buffer form is // the documented fallback. void CallTexBuffer(GLenum target, GLenum internalFormat, GLuint buffer); @@ -448,7 +448,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // hold" query and no way to ask a context for its share group, so a case that must tell "the // same native context still serves" from "a fresh one was built", or a sharing pair from two // unrelated contexts, reads it here. These are pure reads plus one key override; neither is on - // a production path and neither changes behaviour. + // a production path and neither changes behavior. EGLContext NativeContextHandleFor(Uint64 sessionKey, Uint64 contextToken); // Overrides the key the calling thread resolves to, for the life of the call. The backend's // ordinary answer comes from the server layer's probe; this is how a case drives exactly the @@ -484,8 +484,8 @@ namespace MobileGL::MG_Backend::DirectGLES { // Pushes the frontend's render-state block to the ES driver, diffed against what was // last pushed. // - // `forColorClear` names the CALLER, and the only thing it changes is the colour write - // mask handed to the driver. A draw into a colour attachment the backend widened from + // `forColorClear` names the CALLER, and the only thing it changes is the color write + // mask handed to the driver. A draw into a color attachment the backend widened from // three channels to four gets that buffer's alpha channel masked OFF, so nothing can // move the stored alpha away from the 1.0 the application's three-channel format // implies (see FramebufferImpl::g_alphaWidenedDrawBufferMask). A CLEAR is how that 1.0 @@ -494,7 +494,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // followed by a draw re-pushes the mask instead of early-outing on an unchanged // frontend version. // - // The application's own colour mask is never modified: glGet(GL_COLOR_WRITEMASK) + // The application's own color mask is never modified: glGet(GL_COLOR_WRITEMASK) // answers from the frontend state, which this function only reads. void SyncRenderState(Bool forColorClear = false); void InvalidateSyncedRenderState(); diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESBind.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESBind.cpp index 112f5789..c741f7b3 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESBind.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESBind.cpp @@ -636,7 +636,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // BOUNDS-CHECKED, exactly as ProgramObject::GetAttribType is not: the frontend's // form indexes attribTypes raw because the mask it walked came off the same - // artefacts instance, and here the two vectors arrived over a wire. A short tail + // artifacts instance, and here the two vectors arrived over a wire. A short tail // is an archive whose halves disagree; 0 classifies as Unsupported and says so // below rather than reading past the end. const GLenum attribType = location < link.attribTypes.size() ? link.attribTypes[location] : 0; @@ -686,7 +686,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // declined to run it. // // P4a e3 (D-G4) leaves BOTH properties of this gate exactly as they are, and says so - // because they are the kind of thing a later optimisation deletes: + // because they are the kind of thing a later optimization deletes: // // 1. the g_imageUnitHighWaterMark == 0 early-out is what makes every Minecraft draw // pay one integer test, and it is asked BEFORE anything reads a record; @@ -1710,7 +1710,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The last sample a usampler2DMS fetch may name, from the texture // actually bound: a stencil texture's real count is not an integer - // colour texture's. Keyed like the bias above - a texture's storage or + // color texture's. Keyed like the bias above - a texture's storage or // a unit's binding moving is what invalidates this pass's memo. if (samplerBinding.msSampleMaxLocation >= 0) { const Int sampleMax = diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESBlit.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESBlit.cpp index 4a6f7bde..7c5088c3 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESBlit.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESBlit.cpp @@ -107,12 +107,12 @@ namespace MobileGL::MG_Backend::DirectGLES { FramebufferImpl::InvalidateSyncedFramebufferSerial(target); } - // Sized internal format of the currently bound READ framebuffer's read colour + // Sized internal format of the currently bound READ framebuffer's read color // attachment, 0 when it cannot be determined. static GLenum QueryReadColorAttachmentInternalFormat() { GLint attachmentType = 0; GLint attachmentName = 0; - // Ask the point the backend read buffer actually names, not COLOR_ATTACHMENT0. The colour map + // Ask the point the backend read buffer actually names, not COLOR_ATTACHMENT0. The color map // in BackendFramebufferObject is a permutation, so the read attachment's image only sits at // CA0 when that map is identity; querying CA0 unconditionally would size the resolve // renderbuffer from a different attachment's format and either convert wrongly or fail the @@ -561,7 +561,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The guard already left the pipeline neutral (nothing culled, tested, blended or // coverage-masked) on the borrowed texture unit; what is left is this pass's own - // choices - the destination rectangle, and colour writes off because it writes only + // choices - the destination rectangle, and color writes off because it writes only // depth and stencil. VertexArrayImpl::BindBackendVAOId(s_vertexArray); g_GLESFuncs.glBindTexture(GL_TEXTURE_2D, s_texture); @@ -626,7 +626,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // into a scratch framebuffer of the source's own native format, then run the caller's blit // - same mask, same filter, same orientation - from the scratch into the real destination. // Overlapping rectangles stay undefined, as GL leaves them. A LINEAR blit that scales reads - // clamped texels at the rectangle's edge where GL would read the neighbouring ones. + // clamped texels at the rectangle's edge where GL would read the neighboring ones. // What a framebuffer attachment point resolves to on the DRIVER side: the native object and, // for a texture, the level, layer and cube face. A null name means the point is empty. @@ -661,7 +661,7 @@ namespace MobileGL::MG_Backend::DirectGLES { a.Face == b.Face; } - // The colour attachment point the bound READ framebuffer reads from, GL_NONE when it reads + // The color attachment point the bound READ framebuffer reads from, GL_NONE when it reads // nothing. static GLenum DriverReadColorAttachment() { GLint readBuffer = GL_NONE; @@ -878,7 +878,7 @@ namespace MobileGL::MG_Backend::DirectGLES { g_GLESFuncs.glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previousDraw); g_GLESFuncs.glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &previousRead); - // Every point is (re)attached on every call: the scratch is shared between colour and + // Every point is (re)attached on every call: the scratch is shared between color and // depth/stencil shapes, and a stale attachment would make it incomplete or blit an // aspect the source does not have. g_GLESFuncs.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_scratchFramebuffer); @@ -934,7 +934,7 @@ namespace MobileGL::MG_Backend::DirectGLES { return; } // Two ES restrictions desktop GL does not have are worth a second attempt: a - // multisample resolve that also converts colour format, and any blit into a + // multisample resolve that also converts color format, and any blit into a // multisample draw framebuffer. Both need to know how the two sides are sampled. GLint readSamples = 0; GLint drawSamples = 0; @@ -968,21 +968,21 @@ namespace MobileGL::MG_Backend::DirectGLES { if (ReplicateBlitIntoMultisampleDraw(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask)) { if ((mask & GL_COLOR_BUFFER_BIT) != 0) { MGLOG_E_ONCE( - "BlitFramebuffer: colour replicate into a multisample draw framebuffer is not emulated"); + "BlitFramebuffer: color replicate into a multisample draw framebuffer is not emulated"); } } return; } // The combined call raised an error, so by GL 4.6 2.3.1 it wrote nothing at all: BOTH // aspect groups still owe their copy, and each has to be retried on its own. Re-issuing - // the depth/stencil half only as a rider on a SUCCESSFUL colour resolve dropped it - // silently whenever the colour half could not be emulated - and on a framebuffer whose - // only attachment is depth it never can, because the colour emulation has no attachment + // the depth/stencil half only as a rider on a SUCCESSFUL color resolve dropped it + // silently whenever the color half could not be emulated - and on a framebuffer whose + // only attachment is depth it never can, because the color emulation has no attachment // to take a format from (KHR-GL33.framebuffer_blit's depth config test blits // COLOR|DEPTH|STENCIL across depth-only framebuffers and kept reading the clear value). const GLbitfield colourBit = mask & static_cast(GL_COLOR_BUFFER_BIT); const GLbitfield dsBits = mask & static_cast(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - // The colour group's one emulation is the multisample resolve that also converts format, + // The color group's one emulation is the multisample resolve that also converts format, // which is the shape this names. It used to double as an early-out for the whole // function, which is what cost a depth-only mask its single-aspect retry. const Bool multisampleResolve = readSamples > 0 && drawSamples <= 0; @@ -993,7 +993,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const Bool emulated = multisampleResolve && ResolveThenBlit(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, filter); if (!emulated) { - MGLOG_E_ONCE("BlitFramebuffer: the colour aspect was dropped - the driver rejected it on its " + MGLOG_E_ONCE("BlitFramebuffer: the color aspect was dropped - the driver rejected it on its " "own and no emulation applies"); } } @@ -1002,7 +1002,7 @@ namespace MobileGL::MG_Backend::DirectGLES { DrainBlitErrors(); g_GLESFuncs.glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, dsBits, filter); if (g_GLESFuncs.glGetError() != GL_NO_ERROR) { - // Nothing to fall back on yet: ResolveThenBlit is colour-only and the replicate + // Nothing to fall back on yet: ResolveThenBlit is color-only and the replicate // pass runs in the opposite direction, so a driver that declines a multisample // depth/stencil resolve leaves the destination holding its clear value. The log // is the whole diagnostic - the frontend performs no validation of its own, so @@ -1283,7 +1283,7 @@ namespace MobileGL::MG_Backend::DirectGLES { }); MGLOG_D("ES %s(%d, %d, %d, %d, %d, %d, %d, %d, 0x%x, %s)", __func__, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, MG_Util::ConvertGLEnumToString(filter).c_str()); - // A no-op on every driver that honours a non-zero destination array layer, which is all + // A no-op on every driver that honors a non-zero destination array layer, which is all // of them but the probed one. Whatever it performs itself is taken out of the mask. // P5e (fb, §5.4): the bound arm's two binding-slot reads were the last GetBoundObject // pair on this path; under a transport the two bound RECORDS answer instead diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESBuffers.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESBuffers.cpp index 4533a76b..75571be3 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESBuffers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESBuffers.cpp @@ -378,7 +378,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // CountPrimitivesForDraw does not know and for the instanced/indirect entry // points that never call it. MGLOG_E_ONCE("EndTransformFeedback: scattered capture discarded - packedStride=%zu, " - "CPU-modelled captured vertices=%zu, scratch capacity=%zu. The capture buffers keep " + "CPU-modeled captured vertices=%zu, scratch capacity=%zu. The capture buffers keep " "their pre-draw contents.", packedStride, modelledVertices, xfb.scatterCapacityVertices); return; @@ -431,7 +431,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // (glBufferData(size, NULL) with no resource_subdata since), which // M-3 declares legal: every byte the application has not staged is // UNDEFINED by its own declaration, and `staged` is already - // value-initialised to zero - which is byte for byte what the monolith + // value-initialized to zero - which is byte for byte what the monolith // arm scatters over when it reads a fresh MappedData(). Skipping the // Memcpy is therefore the WHOLE of the difference; skipping the TARGET // threw the varyings away and left the application's buffer holding its @@ -669,7 +669,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The frontend VAO is taken ONLY when the applier's own vertex-buffer window says a // client-sourced attribute exists, which is what retires the per-draw // GetBoundVertexArray row of the ordinary (VBO-backed) DrawArrays - the strict lane's - // `GetBoundVertexArray@DrawArrays` marker - without touching this path's behaviour. + // `GetBoundVertexArray@DrawArrays` marker - without touching this path's behavior. // `static` on purpose (G1): the pull build must not gain an exported name for a // function that only re-homes two identical inline blocks the two DrawArrays entry // points used to carry. The same spelling governs the three below, and for a second diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESContext.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESContext.cpp index 59f54515..25231738 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESContext.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESContext.cpp @@ -343,14 +343,14 @@ namespace MobileGL::MG_Backend::DirectGLES { // default framebuffer is answered out of that guess, and being wrong is not cosmetic: GL // blits depth/stencil only between IDENTICAL formats, so a caller that reads // GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, allocates the buffer it was told about and blits - // gets GL_INVALID_OPERATION and a silently dropped blit - colour bits included, because a + // gets GL_INVALID_OPERATION and a silently dropped blit - color bits included, because a // rejected glBlitFramebuffer transfers nothing at all. DirectVulkan already publishes its // real format when it creates the swapchain (SwapchainObject::Create); this is the // DirectGLES half, and here the answer can simply be asked of the ES default framebuffer. // // Only the format is published. The placeholder's 512x512 extent is left alone: all three // attachments share it, and FramebufferObject::CheckCompleteness requires them to agree, so - // resizing depth/stencil without colour would report the default framebuffer incomplete. + // resizing depth/stencil without color would report the default framebuffer incomplete. static void PublishDefaultFramebufferDepthStencilFormat() { auto& defaultFBOInfo = MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo; // P8-SE: THE PLACEHOLDER IS ONLY THE MONOLITH ARM'S TARGET. With a transport the answer is @@ -1550,7 +1550,7 @@ namespace MobileGL::MG_Backend::DirectGLES { return false; } // Clearing the global owner works from ANY thread (a release request can - // legally arrive on a thread other than the current owner); erring towards + // legally arrive on a thread other than the current owner); erring toward // "not current" only defers buffer ops, which is always safe. InvalidateEglVerifiedStamp(); t_native.boundContext = EGL_NO_CONTEXT; diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESCopy.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESCopy.cpp index 9a4171a2..35f367eb 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESCopy.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESCopy.cpp @@ -982,7 +982,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // P8-B2: RGB16F / RGB32F MIP GENERATION ON THE SERVER, FROM THE SERVER'S OWN LEVEL. // - // ES generates a chain only for a colour-renderable, filterable format, and whether the + // ES generates a chain only for a color-renderable, filterable format, and whether the // driver's storage for these two is one depends on the driver: Espryt stores them natively // where the driver renders the three-channel form and widens them to RGBA16F / RGBA32F where // it does not (TextureImpl::BackendTextureFormatAddsAlpha), and a widened RGBA32F still needs @@ -1249,7 +1249,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #if MOBILEGL_LOG_ACTIVE_LEVEL <= MOBILEGL_LOG_LEVEL_DEBUG && MOBILEGL_ENABLE_SCOPE_MARKER DebugImpl::OpenGLScopeMarker marker(__func__); #endif - // P5e (tx2), CONTRACT-P5E §5.2 / ruling 14 (ID-92's neighbour): GENERATE_MIPMAP RESOLVES + // P5e (tx2), CONTRACT-P5E §5.2 / ruling 14 (ID-92's neighbor): GENERATE_MIPMAP RESOLVES // ITS TEXTURE FROM VerbMipRes, NEVER FROM THE ACTIVE UNIT. // // The verb's own record names the texture (MGPMipPlan::Res, stashed as VerbMipRes) and @@ -1634,7 +1634,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The frontend has already recorded the rebinding on the program object // (SetShaderStorageBlockBinding) - that record is what GL_BUFFER_BINDING reports and what // BackendProgramObjectImpl::SyncToBackend replays onto every driver program it builds. So - // the only work left here is an optimisation: push the change straight onto a driver + // the only work left here is an optimization: push the change straight onto a driver // program that is ALREADY built and already current with this link, so the next draw does // not have to be preceded by a rebuild. // @@ -1667,7 +1667,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } namespace { - // A colour attachment the backend widened from three channels to four has to end up + // A color attachment the backend widened from three channels to four has to end up // holding alpha 1.0 - the value GL reports for a channel the application's format does // not have - so an explicit per-buffer clear of it writes 1.0 rather than whatever the // application passed (SubstituteWidenedClearAlpha, in Managers.h). Draws can never move diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESDraw.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESDraw.cpp index ca87f348..cf078b79 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESDraw.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESDraw.cpp @@ -59,7 +59,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // P5e (mv): THE ARM SELECTOR of this family - VertexInputReadsRecords() - moved to // Managers.h, unchanged. MultiDraw.cpp is a second translation unit on the same draw // path and has to select the same arm; a copy of the conjunction there would be two - // selectors for one family. Its rationale travelled with it. + // selectors for one family. Its rationale traveled with it. // P5e (vi): "does this draw fetch any attribute out of the application's own memory", // answered FROM THE RECORD instead of from the frontend VAO. The emitter publishes @@ -238,7 +238,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // feedback records per emitted primitive, so a replayed draw would write its vertices N // times; rasterizer discard means there are no fragments to gate at all, so replaying // would be pure cost with nothing to show for it. Both fall back to a single pass with an - // open gate, i.e. to the pre-emulation behaviour, rather than to wrong data. + // open gate, i.e. to the pre-emulation behavior, rather than to wrong data. if (MG_Pipe::gPipeInputs->IsTransformFeedbackActive() || MG_Pipe::gPipeInputs->IsCapabilityEnabled(CapabilityInput::RasterizerDiscard)) { return 1; @@ -521,7 +521,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #endif TextureImpl::SyncNeccessaryTextures(); FramebufferImpl::SyncCurrentFBO(); - // A colour clear is exactly the operation that is allowed to write a widened + // A color clear is exactly the operation that is allowed to write a widened // attachment's alpha - it is what puts the 1.0 there that every later draw is masked // away from. SyncCurrentFBO ran first, so g_alphaWidenedDrawBufferMask already describes // the framebuffer this clear will land on. @@ -565,17 +565,17 @@ namespace MobileGL::MG_Backend::DirectGLES { const Bool outOfRange = cc.x() < 0.f || cc.x() > 1.f || cc.y() < 0.f || cc.y() > 1.f || cc.z() < 0.f || cc.z() > 1.f || cc.w() < 0.f || cc.w() > 1.f; // A widened attachment's stored alpha has to end up 1.0, and glClear applies ONE - // clear colour to every draw buffer - so a framebuffer that mixes a widened + // clear color to every draw buffer - so a framebuffer that mixes a widened // attachment with a native one cannot be served by doctoring glClearColor. Take the // same per-draw-buffer glClearBufferfv route the out-of-range case already uses and - // substitute the alpha only where it belongs. Scissor and the colour write mask apply + // substitute the alpha only where it belongs. Scissor and the color write mask apply // to glClearBufferfv exactly as they do to glClear, so a scissored clear stays // scissored and an application that masked alpha off still gets its way (the storage // then keeps the 1.0 an earlier clear left, which is the same answer). // - // glClearBufferfv on an INTEGER colour buffer is GL_INVALID_OPERATION, so a + // glClearBufferfv on an INTEGER color buffer is GL_INVALID_OPERATION, so a // framebuffer with one of those as a draw buffer keeps plain glClear - which ES - // leaves undefined for integer colour buffers anyway, and which an application that + // leaves undefined for integer color buffers anyway, and which an application that // wants a defined answer must replace with glClearBufferuiv/iv (those DO substitute // the widened alpha). The out-of-range trigger is left exactly as it was. const Uint32 widenedDrawBuffers = FramebufferImpl::g_alphaWidenedDrawBufferMask; diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESInternal.h b/MobileGL/MG_Backend/DirectGLES/DirectGLESInternal.h index 26aaf60e..6bb55873 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESInternal.h +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESInternal.h @@ -611,9 +611,9 @@ namespace MobileGL::MG_Backend::DirectGLES { SamplerImpl::UnbindSampler(TextureImpl::TempTextureUnit); // The neutral baseline every emulation pass wants: nothing culled, nothing - // clipped, nothing tested, no coverage games, and colour writes open. Callers + // clipped, nothing tested, no coverage games, and color writes open. Callers // turn back on only what they need (the replicate pass wants the depth and - // stencil tests, and masks colour off because it writes neither). + // stencil tests, and masks color off because it writes neither). for (Uint i = 0; i < m_capabilityCount; ++i) { g_GLESFuncs.glDisable(m_capabilities[i].cap); } @@ -652,7 +652,7 @@ namespace MobileGL::MG_Backend::DirectGLES { g_GLESFuncs.glDisable(m_capabilities[i].cap); } } - // The per-draw-buffer colour masks are not covered by the non-indexed + // The per-draw-buffer color masks are not covered by the non-indexed // glColorMask above. Restore what the SYNC actually pushed, not the raw // application masks: a widened attachment's alpha write is forced off by // SyncRenderState and memoized in g_syncedColorMaskAlphaWidenMask, and the @@ -886,7 +886,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // DirectGLESReadback.cpp defines it: E's extent-scoped stand-in for a - // driver that refuses to read a colour level back, asked here too so a host reaches the store + // driver that refuses to read a color level back, asked here too so a host reaches the store // route below (P8-SE). Bool WireTextureReadbackRefusedForTesting(const IntVec3& extent); using FramebufferImpl::SubstituteWidenedClearAlpha; diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESReadback.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESReadback.cpp index 0ab17f7b..a33cdf72 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESReadback.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESReadback.cpp @@ -111,10 +111,10 @@ namespace MobileGL::MG_Backend::DirectGLES { // it on the way). ES rejects a depth/stencil blit between differing formats, so // the scratch has to match the source exactly; see DescribeReadDepthStencilSource. // 2. Convert. Draw a full-screen triangle that samples the staged texture into a - // scratch R32UI colour target: depth as floatBitsToUint (bit-exact for every depth - // format, and an integer colour target needs no float-renderable extension), + // scratch R32UI color target: depth as floatBitsToUint (bit-exact for every depth + // format, and an integer color target needs no float-renderable extension), // stencil through GL_DEPTH_STENCIL_TEXTURE_MODE = GL_STENCIL_INDEX. - // 3. Read. glReadPixels the colour target with GL_RGBA_INTEGER / GL_UNSIGNED_INT - + // 3. Read. glReadPixels the color target with GL_RGBA_INTEGER / GL_UNSIGNED_INT - // the pair ES guarantees for an unsigned-integer attachment - and hand the values // to the existing re-encoders, which already own the client-side (format, type) // layout and the PACK pixel-store parameters. @@ -407,7 +407,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (s_colorTexture == 0) return false; g_GLESFuncs.glBindTexture(GL_TEXTURE_2D, s_colorTexture); ClearGLErrors(); - // R32UI is colour-renderable in ES 3.0 core - no float-renderability extension + // R32UI is color-renderable in ES 3.0 core - no float-renderability extension // needed - and carries a depth bit pattern or a stencil index without loss. g_GLESFuncs.glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32UI, s_colorWidth, s_colorHeight); const Bool ok = g_GLESFuncs.glGetError() == GL_NO_ERROR; @@ -458,7 +458,7 @@ namespace MobileGL::MG_Backend::DirectGLES { return false; } - // Runs one conversion pass over a staged slot and reads its colour target back. + // Runs one conversion pass over a staged slot and reads its color target back. // Requires the slot's texture bound on the borrowed unit and s_colorFramebuffer // bound as DRAW. static Bool ConvertAndRead(const StageSlot& slot, Bool stencilAspect, GLsizei width, GLsizei height, @@ -625,7 +625,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Neither native spelling exists on this driver (which is the ordinary case: ES has // no depth readback in core and GL_NV_read_depth is rare), so sample the attachment // instead. The scoped pack state above is irrelevant to that path - it reads its own - // scratch colour target - but harmless, and leaving it in place keeps the restore in + // scratch color target - but harmless, and leaving it in place keeps the restore in // one place. if (DepthStencilSamplingReadImpl::Read(x, y, width, height, &outDepth, /*outStencil=*/nullptr)) { return true; @@ -636,7 +636,7 @@ namespace MobileGL::MG_Backend::DirectGLES { return false; } - // GL_DEPTH_COMPONENT readback into the client's layout, honouring the PACK pixel-store + // GL_DEPTH_COMPONENT readback into the client's layout, honoring the PACK pixel-store // parameters. GL 4.6 core 18.2.8 table 8.6: the normalized depth is written as-is for the // floating-point client types and scaled into the full range of whichever integer width the // client asked for otherwise - 2^n - 1 for an unsigned width, 2^(n-1) - 1 for a signed one. @@ -764,7 +764,7 @@ namespace MobileGL::MG_Backend::DirectGLES { return false; } - // GL_STENCIL_INDEX readback into the client's integer layout, honouring the PACK + // GL_STENCIL_INDEX readback into the client's integer layout, honoring the PACK // pixel-store parameters. Handles the widths desktop clients ask for; the stencil // values themselves are always 8 bits. static Bool ReadPixelsStencilViaNative(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type, void* pixels) { @@ -964,7 +964,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // Overwrites the alpha of a 4-channel wide read with the format's implied 1.0. Used for an - // attachment the backend widened from three channels to keep it colour-renderable: the storage + // attachment the backend widened from three channels to keep it color-renderable: the storage // has a real alpha channel holding whatever the draw wrote, but the format the application // asked for has none, and GL reads a missing channel back as one. static void ForceWideReadAlphaToOne(Vector& data, SizeT pixelCount, GLenum componentType) { @@ -1033,7 +1033,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // (format, type) layout. Returns false when the combination is not convertible (the caller keeps its // "not implemented" skip); returns true when the request was handled, even if it degraded to a logged no-op. // `forceOpaqueAlpha`: the source image is a three-channel format the backend widened to four to - // keep it colour-renderable, so its alpha channel holds whatever the draw wrote and has to be + // keep it color-renderable, so its alpha channel holds whatever the draw wrote and has to be // answered with the 1.0 the application's format implies. Passed in rather than derived here: // glReadPixels reads the bound READ framebuffer, but glGetTexImage reads a texture through a // scratch framebuffer, so the frontend's READ binding describes a different image entirely - @@ -1230,7 +1230,7 @@ namespace MobileGL::MG_Backend::DirectGLES { ForceWideReadAlphaToOne(wide, static_cast(width) * static_cast(height), wideType); } - // GL clamps a read from a fixed-point colour buffer to [0,1] (GL_CLAMP_READ_COLOR + // GL clamps a read from a fixed-point color buffer to [0,1] (GL_CLAMP_READ_COLOR // defaults to GL_FIXED_ONLY). Formats the backend substitutes with a floating-point // one keep the out-of-range value the app stored, so apply the clamp here - a // GL_R16_SNORM target holding -0.125 must still read back as 0. @@ -1283,13 +1283,13 @@ namespace MobileGL::MG_Backend::DirectGLES { return true; } - // ---- Bit-exact readback of a 32-bit packed colour level --------------------------------------- + // ---- Bit-exact readback of a 32-bit packed color level --------------------------------------- // // glGetTexImage of a packed format read with its OWN client type owes the application the words // the image HOLDS, and neither of the two routes above can promise that once anything other than // a glTexImage has written the level: // - // * the colour-attachment route reads GL_RGBA/GL_FLOAT and re-encodes, which canonicalizes an + // * the color-attachment route reads GL_RGBA/GL_FLOAT and re-encodes, which canonicalizes an // RGB9_E5 shared exponent (0xf8fc0000 -> 0xe7e00000, same value, different bits) and // collapses an R11F_G11F_B10F NaN to the canonical payload 1 // (MG_Util::EncodeFloatToUnsignedSmallFloat) - and a copy-image from RGB9_E5 lands exactly @@ -1301,7 +1301,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // source (which has no shadow to mirror from at all), a cube or 1D-array endpoint, a // self-copy - and the decline is silent, so the stale words are served as truth. // - // glCopyImageSubData is a raw texel-block move and EXT_copy_image puts every 32-bit colour + // glCopyImageSubData is a raw texel-block move and EXT_copy_image puts every 32-bit color // format in one compatibility class, so copying the level into a scratch GL_R32UI image and // reading THAT back as unsigned integers hands over the stored words themselves, whoever wrote // them. This is what lets the shadow stop being the authority for these formats: it is tried @@ -1387,7 +1387,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // GL_RGBA_INTEGER/GL_UNSIGNED_INT is the one combination ES guarantees for an integer - // colour buffer, so the read lands four words per texel and the red one is compacted out + // color buffer, so the read lands four words per texel and the red one is compacted out // here. The PACK scope is the tight default rather than the application's, so a row comes // back packed at exactly `width * 4` words. One glGetError covers the whole loop: it // accumulates, and a failure anywhere means the caller falls back rather than trusting a @@ -1796,7 +1796,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // P8-E. MGITEST_ESPRYT_REFUSE_TEXTURE_READBACK_EXTENT=x, READ BY THE SERVER: - // a colour level of exactly that extent is treated as one the driver refused to attach - what an + // a color level of exactly that extent is treated as one the driver refused to attach - what an // Adreno does for RGB16 and the 16-bit SNORM formats, and what no host driver can be made to do. // Scoped by the extent so the tcp lane's shared supervisor can carry it for the whole lane: only // the scenario that builds that extent (CopyImageStoreReadbackScenario) ever meets it. @@ -1954,7 +1954,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // The (format, type) pairs the depth/stencil helpers below can service. They are not - // covered by the colour tables above - GetReadbackChannelMapping has no entry for any + // covered by the color tables above - GetReadbackChannelMapping has no entry for any // depth or stencil format, so without this gate a read the helpers CAN serve (a // GL_UNSIGNED_SHORT depth, a GL_SHORT stencil) is turned away before it reaches them. // The signed widths and GL_HALF_FLOAT belong in it for the same reason: the helpers scale a @@ -2025,7 +2025,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The read buffer is what glReadPixels reads, so the frontend's READ binding is exactly // the right thing to ask here. const Bool forceOpaqueAlpha = FramebufferImpl::IsAlphaWidenedFallbackReadAttachment(); - // An attachment widened from three channels to stay colour-renderable also has to leave + // An attachment widened from three channels to stay color-renderable also has to leave // the fast pair: only the conversion path knows to answer its alpha with the 1.0 the // application's format implies instead of whatever the draw wrote into the added channel. const Bool nativeFastPair = !packSwapBytes && !forceOpaqueAlpha && diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESSharedImage.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESSharedImage.cpp index 078eaf0d..3b006fa1 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESSharedImage.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESSharedImage.cpp @@ -56,7 +56,7 @@ namespace MobileGL::MG_Backend::DirectGLES { DupNativeFenceFdFn DupNativeFenceFd = nullptr; // YUV images: sampled as external textures (GL_OES_EGL_image_external_essl3), and // through GL_EXT_YUV_target's raw Y'CbCr sampler where the driver has it, so the - // conversion is the import's own (its colour hints) rather than the driver's guess. + // conversion is the import's own (its color hints) rather than the driver's guess. Bool ExternalEssl3 = false; Bool YuvTarget = false; }; @@ -573,7 +573,7 @@ namespace MobileGL::MG_Backend::DirectGLES { conversion.TargetOffset = g_GLESFuncs.glGetUniformLocation(program, "uOffset"); } MGLOG_I("Shared images: YUV images convert through %s", - ownConversion ? "GL_EXT_YUV_target with the import's colour hints" + ownConversion ? "GL_EXT_YUV_target with the import's color hints" : "the driver's external-sampler conversion"); } if (conversion.Framebuffer == 0) g_GLESFuncs.glGenFramebuffers(1, &conversion.Framebuffer); diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESState.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESState.cpp index 3055972b..ff4976a8 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESState.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESState.cpp @@ -30,7 +30,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // // The cache stays on the LEGACY arm, gated on the same subsystem bit as the rest of this // slice, so that MOBILEGL_PIPE_PUSH=0 keeps being the faithful all-subsystems-pull control - // ConfigLoader.cpp documents - "reproduces P1's behaviour exactly" has to include this + // ConfigLoader.cpp documents - "reproduces P1's behavior exactly" has to include this // path, or the integrator's A/B measures e4 on both arms and attributes it to neither. In // the pull build gPipeInputs is the live GLContext, there is no poison to bypass and the // frontend getter still linear-scans, so the cache is exactly the code it was. @@ -339,9 +339,9 @@ namespace MobileGL::MG_Backend::DirectGLES { // direct_state_access.renderbuffers_storage. One unconditional push settles the whole // block rather than the one cap that happened to be noticed. static Bool g_forceFullRenderStateResync = true; - // Which draw buffers' alpha channel the colour mask last pushed to the driver had forced + // Which draw buffers' alpha channel the color mask last pushed to the driver had forced // OFF - i.e. the value of `appliedWidenMask` in the last SyncRenderState that reached the - // colour-mask block. NOT derivable from the frontend parameter block: it depends on the + // color-mask block. NOT derivable from the frontend parameter block: it depends on the // bound DRAW framebuffer's attachment formats and on whether the caller is a draw or a // clear, neither of which bumps the frontend render-state version. Without it a // clear-then-draw pair on an unchanged parameter block early-outs and the draw inherits @@ -405,7 +405,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Uint16 currentRenderStateVersion = MG_Pipe::gPipeInputs->GetRenderStateParametersVersion(); const Bool forceFullPush = g_forceFullRenderStateResync; g_forceFullRenderStateResync = false; - // The alpha discipline for widened colour attachments (see the header comment on + // The alpha discipline for widened color attachments (see the header comment on // SyncRenderState): a DRAW must not be able to move the stored alpha off 1.0, a CLEAR // is what puts it there. So the draw path masks alpha off on every widened draw // buffer and the clear path masks nothing. @@ -539,7 +539,7 @@ namespace MobileGL::MG_Backend::DirectGLES { { // sRGB framebuffer writes. GLES core always encodes a write into an sRGB attachment, // while GL_FRAMEBUFFER_SRGB is disabled by default in desktop GL and the frontend // never turns it on, so the driver has to be told to write raw. Without this a render - // into an sRGB colour buffer comes back encoded once too often (the shader's own + // into an sRGB color buffer comes back encoded once too often (the shader's own // decode on the next fetch then leaves the value one conversion short). const Bool srgbWrites = MG_Pipe::gPipeInputs->IsCapabilityEnabled(CapabilityInput::FramebufferSrgb); if (g_GLESCapabilities.SupportsSrgbWriteControl && @@ -853,7 +853,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // framebuffer, so a widened draw buffer 0 costs every other buffer its // alpha writes. ES 3.2 makes glColorMaski core and ES 3.1 has it as // EXT/OES; the only devices that reach this line are ES 3.0-class, where - // MRT with a mixed widened/native colour attachment set is already rare. + // MRT with a mixed widened/native color attachment set is already rare. const BoolVec4& m = driverMask0; g_GLESFuncs.glColorMask(ToGLBoolean(m.x()), ToGLBoolean(m.y()), ToGLBoolean(m.z()), ToGLBoolean(m.w())); diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESSync.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESSync.cpp index fcc2fb01..622a1084 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESSync.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESSync.cpp @@ -601,7 +601,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // spelling the driver provides (Adreno exposes only eglSwapBuffersWithDamageKHR), so // the null check below is the whole chain: a driver with neither presents with plain // eglSwapBuffers. Passing n_rects == 0 is not a partial present - the extension - // defines it as "the entire surface is implicitly damaged and the behaviour is + // defines it as "the entire surface is implicitly damaged and the behavior is // equivalent to calling eglSwapBuffers" - and the wire protocol carries no damage // rectangles for the server to forward, so the full surface is what is meant anyway. // diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLESTextures.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLESTextures.cpp index 17960f2d..3cd3be8c 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLESTextures.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLESTextures.cpp @@ -35,7 +35,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // two never-synced textures as equal. The identity has to exist before the twin does. // // Split by the RUNTIME arm, not by the build, for exactly the reason g_fbSlotCache is: - // MOBILEGL_PIPE_PUSH=0 has to reproduce P1's behaviour (ConfigLoader.cpp), and a + // MOBILEGL_PIPE_PUSH=0 has to reproduce P1's behavior (ConfigLoader.cpp), and a // legacy-arm run that debounced on lifetime ids would be running P2's mechanism while // the A/B attributed the result to P1. The two answers are equivalent - OwnerEquals on // two empty pointers is true and LifetimeIdOf(nullptr) == 0 == 0; a live-versus-expired @@ -454,7 +454,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // // A texture that is an attachment of the READ framebuffer ONLY reaches // SyncAttachmentObject, which calls SyncMipmapsToBackend AND NOTHING ELSE - so its - // swizzle, its GL_DEPTH_STENCIL_TEXTURE_MODE, its LOD clamp and its border colour + // swizzle, its GL_DEPTH_STENCIL_TEXTURE_MODE, its LOD clamp and its border color // never reach the driver. The list that pushes texture PARAMETERS for an attachment is // the one below, and it reads the DRAW binding slot alone. That is the gap // ARCHITECTURE.md's D10 names, and the roadmap makes closing it a mandatory, @@ -464,7 +464,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // // DELIBERATELY NOT GATED ON THE FRAMEBUFFER SUBSYSTEM BIT. It is a deliverable of the // phase rather than an arm of it, so both arms of the object A/B carry it and the A/B - // keeps measuring the arm rather than the arm plus a behaviour change. It is inside + // keeps measuring the arm rather than the arm plus a behavior change. It is inside // MOBILEGL_PIPE_PUSH, so the pull build is untouched. // // Its own list and its own key rather than an extension of the draw list's, because @@ -562,7 +562,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // and the alias contest between two real textures on one native target was arbitrated // by the program's own sampler types. So the window IS the work list. // - // NAMED BEHAVIOUR DELTA (P5e-5, contract §5.2): this syncs the PROGRAM-RESOLVED + // NAMED BEHAVIOR DELTA (P5e-5, contract §5.2): this syncs the PROGRAM-RESOLVED // texture per unit, where the frontend walk syncs every slot of every touched unit. // Coverage is unchanged - views UNION image units UNION the FBO attachment lists // UNION the waited texture ops still cover every texture anything reads - so it diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 212a91dd..a0550f51 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -212,7 +212,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // InProcessTeardown() - touches neither the driver nor another TU's statics. // // P14 S6: "EVERY TABLE" IS NOW "EVERY BUCKET OF THIS SESSION". The tables are keyed by - // {session, share group}, so the same rebuild of the eight registries would take a NEIGHBOUR + // {session, share group}, so the same rebuild of the eight registries would take a NEIGHBOR // session's twins with it - and with S2's in-process supervisor serving several sessions at // once that is not a hypothetical: this runs from ~BackendObject_DirectGLES, on the apply // thread of the session that is ending. So the drop is scoped to the calling thread's @@ -533,7 +533,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Fragment stage. Returns false when the stage has no entry point to gate onto, which the // caller reports: the program still links and still renders, it just renders every index - // with the first replay pass's state - i.e. it degrades to the pre-emulation behaviour + // with the first replay pass's state - i.e. it degrades to the pre-emulation behavior // rather than to a black screen. Bool InjectViewportIndexPassGate(String& source) { // Built beside the input and swapped in only on success, so a stage this pass declines @@ -879,7 +879,7 @@ namespace MobileGL::MG_Backend::DirectGLES { "MGPFramebufferState::Color[%u]'s wire width", cap, MG_Pipe::kMGPipeMaxColorAttachments); BufferImpl::StopOnArmlessPipeSubsystem( - "kMGPipeSubsystemFramebuffer (bit 9) cannot carry this driver's colour attachments, and " + "kMGPipeSubsystemFramebuffer (bit 9) cannot carry this driver's color attachments, and " "the record arm is the only arm since P13 W6"); } } @@ -914,7 +914,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (!TextureImpl::IsMultisampleTextureTarget(target)) return 0; // The same three inputs the storage allocation clamps with (SyncToBackend's multisample // arm): the record's format and requested count, and the format's ES transfer format, - // which only decides the integer-vs-colour fallback when the probe has no answer. + // which only decides the integer-vs-color fallback when the probe has no answer. const auto internalFormat = static_cast(record->Desc.InternalFormat); GLenum glInternalFormat = 0, glFormat = 0, glType = 0; TextureImpl::GenerateTextureFormatInfo(internalFormat, &glInternalFormat, &glFormat, &glType, target); @@ -931,7 +931,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // N-7: D KEYS ON THE UPLOAD HALF; WIRE (AccumulatePendingUpload, PipeApply.cpp) KEYS ON - // THE WHOLE PACKED FIELD. That asymmetry is resolved HERE, in D's favour and with the + // THE WHOLE PACKED FIELD. That asymmetry is resolved HERE, in D's favor and with the // reason, rather than by widening the two comparisons: D's question is per (uploadTarget, // level) because that is the granularity its upload loop iterates - it is handed a // TextureUploadTarget and a level and has no second key to offer - while wire's is per diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.h b/MobileGL/MG_Backend/DirectGLES/Managers.h index 80728968..fae5c65e 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.h +++ b/MobileGL/MG_Backend/DirectGLES/Managers.h @@ -198,7 +198,7 @@ namespace MobileGL::MG_Backend::DirectGLES { GLenum IndexType() const { return m_indexType; } private: - // Declared before m_capOverride so it is initialised first (members initialise in + // Declared before m_capOverride so it is initialized first (members initialize in // declaration order): the whole decision is made once, and both the cap override and the // constructor body read the same answer. RestartSubstitutionKind m_kind = RestartSubstitutionKind::None; @@ -248,7 +248,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Indices whose whole state tuple (viewport rectangle, scissor rectangle, scissor-test enable, // depth range) is identical share ONE pass, so the overwhelmingly common case - every index // still holding what glViewport/glScissor/glDepthRange broadcast to all sixteen - collapses - // to a single pass with an all-ones gate mask, i.e. one draw and no behaviour change at all. + // to a single pass with an all-ones gate mask, i.e. one draw and no behavior change at all. // // Whether emulation runs. Off only under MOBILEGL_ESPRYT_FORCE_VIEWPORT_ARRAY_EMULATION falsy, which // restores the pre-emulation path as a negative control. @@ -527,7 +527,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Bool ResolveProgramSubsystemArm(); // P13 W6: every family runs the record arm - the frontend arms these resolvers used to choose // between are gone, so no draw-path site asks them any more (the integration peeks still read - // the latches). The one refusal a running process can still meet - a driver whose colour- + // the latches). The one refusal a running process can still meet - a driver whose color- // attachment cap exceeds the wire's width - is checked once, at capability bring-up. void ResolveRecordArmFamilies(); @@ -843,7 +843,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // glBufferStorageExternalEXT, so `id` is immutable, persistentMapped and // persistentPtr is this server's own coherent map of the client's pages. The // reference is this twin's own, released only after a fence that follows the - // store's last use has signalled (RetireT0Import). Survives an ES context loss: + // store's last use has signaled (RetireT0Import). Survives an ES context loss: // the next ensure re-imports it. Null for every store T0 did not adopt. void* externalAhb = nullptr; // P8-C: A SHADER WROTE THIS STORE ON THIS SIDE since the R-11 staged copy (or, for @@ -1632,7 +1632,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // Components per texel the frontend format's client data carries, for the three-channel - // formats that can be widened to a four-channel colour-renderable target; 0 for everything + // formats that can be widened to a four-channel color-renderable target; 0 for everything // else. See PrepareChannelWidenedUpload. Uint GetWidenableClientComponentCount(TextureInternalFormat format); @@ -1642,7 +1642,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Bool IsIntegerWidenableFormat(TextureInternalFormat format); // Repacks three-component client data as four components with an alpha of 1.0 in - // `uploadType`, for a format the backend widened to keep a colour attachment renderable. + // `uploadType`, for a format the backend widened to keep a color attachment renderable. // Returns `data` untouched when no widening applies. Pure CPU and context-free so a unit // test can exercise the exact packing the driver is handed; `widenedData` is the caller's // scratch buffer and has to outlive the returned pointer. @@ -1921,7 +1921,7 @@ namespace MobileGL::MG_Backend::DirectGLES { SamplerParameters m_cacheSamplerParameters; UintVec2 m_cacheLodRange = {0, 1000}; // All three representations plus the form, because none of them alone identifies the - // border colour the driver texture is holding: two integer borders can share one float + // border color the driver texture is holding: two integer borders can share one float // (anything differing above 2^24), and a Float -> Int transition can leave every number // unchanged while still needing a different driver entry point. FloatVec4 m_cacheBorderColor = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -1975,7 +1975,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Hands back the whole RECORD rather than its Params, because the parameter push // reads two things from beside them: Desc.InternalFormat, which decides the two // channel-widening swizzle compositions, and Params.BuiltinSampler, which is where - // the border colour lives (it is sampler state, GL 4.6 table 23.18, and P4a does + // the border color lives (it is sampler state, GL 4.6 table 23.18, and P4a does // not duplicate it onto MGPTextureParams). const MG_Pipe::MGPipeResourceRecord* ResolvePushedTextureParams( const SharedPtr& stateTextureObject); @@ -1994,7 +1994,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // m_syncedShapeParamsVersion) AND m_syncedContentVersion: the applier bumps it on // every respecify and every sub-data it applies to this resource, which is exactly // the union those four covered, without the coarse "any texture's churn re-opens - // every gate" behaviour the sampling-resolution generation had. + // every gate" behavior the sampling-resolution generation had. Uint64 m_syncedResourceSerial = 0; // The record's ParamsSerial at the last SyncTextureParamsToBackend. Replaces // m_syncedTextureParamsVersion; MGPTextureParams::ForceResync replaces @@ -2186,7 +2186,7 @@ namespace MobileGL::MG_Backend::DirectGLES { framebuffer, as a GL_COLOR_ATTACHMENTm enum. ES only accepts glDrawBuffers bufs[s] == GL_COLOR_ATTACHMENTs, so a GL draw-buffer slot s naming attachment a forces a's image under backend slot s. This table is the single owner of that decision and is kept a - PERMUTATION of the backend colour slots: every other attachment keeps its identity + PERMUTATION of the backend color slots: every other attachment keeps its identity slot when that slot survived, and is parked on the lowest free slot when it did not. Deriving the point per-query from the draw-buffer array instead handed the identity point to any attachment that was not a draw buffer - i.e. exactly the point a @@ -2248,7 +2248,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // false accounts of one physical state: a composite framebuffer synced as DRAW in a // depth pre-pass detaches the points its other attachment state attaches, and the // end-of-frame sync of that same record on the READ side then found its own slot - // already stamped by an earlier identical sync, walked nothing, left the colour point + // already stamped by an earlier identical sync, walked nothing, left the color point // detached, and the driver refused the following glBlitFramebuffer with // INVALID_OPERATION. Keying on the object is what makes "this hash is applied" mean // "these points are on the driver now". @@ -2305,7 +2305,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // describe that point at all (Color8..Color31, and the default framebuffer's FRONT/BACK // tokens). MGPFramebufferState carries Color[8] + Depth + Stencil, which is every point // a framebuffer can hold on the handle arm - D-C3 refuses bit 9 outright on a driver - // reporting more than 8 colour attachments. P5e (fb) exports it: the twin's attachment + // reporting more than 8 color attachments. P5e (fb) exports it: the twin's attachment // walk, the named blit's aspect plan and the detach walk all ask the same question of // the same record, and a second copy of the Color/Depth/Stencil dispatch beside each of // them is how one of them ends up describing a point differently from the others. @@ -2313,13 +2313,13 @@ namespace MobileGL::MG_Backend::DirectGLES { FramebufferAttachmentType point); // True when the read buffer names a fixed-point (norm/snorm) attachment that the // backend actually stores in a floating-point format. GL clamps a read from a - // fixed-point colour buffer to [0,1] (GL_CLAMP_READ_COLOR defaults to + // fixed-point color buffer to [0,1] (GL_CLAMP_READ_COLOR defaults to // GL_FIXED_ONLY); the substituted float storage would not, so the readback path // has to apply the clamp itself. Bool IsFixedPointFallbackReadAttachment(); // True when the read buffer names a three-channel attachment the backend actually stores - // in a four-channel format (the colour-renderable widening). A format without alpha reads + // in a four-channel format (the color-renderable widening). A format without alpha reads // back as 1.0, so the readback path has to overwrite the alpha the draw left behind - // unconditionally, since this is the format's own semantics rather than the // GL_CLAMP_READ_COLOR rule the clamp above implements. @@ -2337,19 +2337,19 @@ namespace MobileGL::MG_Backend::DirectGLES { // driver where no interception is possible. So the stored alpha is kept at 1.0 instead: // a clear touching a widened buffer writes alpha 1.0, and every draw into it has its // alpha write mask forced off, so nothing can ever move it again. The application's own - // colour mask is untouched - glGet(GL_COLOR_WRITEMASK) still reports what it set. + // color mask is untouched - glGet(GL_COLOR_WRITEMASK) still reports what it set. extern Uint32 g_alphaWidenedDrawBufferMask; - // Bit i set = DRAW BUFFER i of the framebuffer bound as DRAW resolves to a colour + // Bit i set = DRAW BUFFER i of the framebuffer bound as DRAW resolves to a color // attachment with an INTEGER format. Recomputed beside the mask above and for its sake: - // glClearBufferfv on an integer colour buffer is GL_INVALID_OPERATION, so the + // glClearBufferfv on an integer color buffer is GL_INVALID_OPERATION, so the // per-draw-buffer clear route the widening needs has to stand down when one is present. - // (glClear on an integer colour buffer is left undefined by ES in the first place, and + // (glClear on an integer color buffer is left undefined by ES in the first place, and // an application that wants a defined answer has to call glClearBufferuiv/iv - which does // carry the widened alpha substitution.) extern Uint32 g_integerColorDrawBufferMask; - // The colour a clear has to hand the driver for one draw buffer: the application's value, + // The color a clear has to hand the driver for one draw buffer: the application's value, // except that a widened attachment's alpha is replaced by the 1.0 its three-channel // format implies. `one` is 1.0 encoded in the clear call's own component type - the // integer clears carry the integer 1, the float clear carries 1.0f. @@ -2909,7 +2909,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // self-contained would produce a per-draw rebuild: the other eight inputs - the draw // FBO's snorm/unorm clamp masks, the fragColor broadcast count, the storage-block // binding signature, the atomic-counter set, the live image formats and the patch - // parameters - are all still specialised at the verb, from state this backend holds. + // parameters - are all still specialized at the verb, from state this backend holds. // 0 means "never stamped", which is a guaranteed miss (applier serials start at 1). Uint64 GetSyncedShaderCsoSerial() const { return m_syncedShaderCsoSerial; } // P5e (pg): the SECOND server-owned key, and it replaces GetImageUnitVersion() on diff --git a/MobileGL/MG_Backend/DirectGLES/ManagersBuffers.cpp b/MobileGL/MG_Backend/DirectGLES/ManagersBuffers.cpp index ff84c27e..bae9df74 100644 --- a/MobileGL/MG_Backend/DirectGLES/ManagersBuffers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/ManagersBuffers.cpp @@ -321,7 +321,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // (Ops_H_ImportExternal below). The twin holds its own reference, and every path that // ends the store - a respecify, a destroy, a re-import - deletes the GL id and then // RETIRES the reference here: a fence is inserted after the delete, and the reference is - // released only once that fence has signalled, i.e. once every command that could still + // released only once that fence has signaled, i.e. once every command that could still // read or write the pages has completed on this context's GPU. The client's own // reference ends independently (it releases on respecify/destroy); the pages live until // the last of the two. No link watermark is involved (F-L2): the fence is this server's. @@ -1046,8 +1046,9 @@ namespace MobileGL::MG_Backend::DirectGLES { // sees the reconciled shadow on return, exactly as before. // // THE ORDER FROM HERE IS A CORRECTNESS RULE, NOT A PREFERENCE - // (ARCHITECTURE.md 8.2: "写回的 epoch bump 必须在任何后续读该 handle 的命令之前被 - // server 应用;反向通道需要与正向通道相同的有序保证"): + // (ARCHITECTURE.md 8.2: "the writeback's epoch bump must be applied by the server before any + // later command that reads that handle; the reverse channel needs the same ordering guarantees as the + // forward channel"): // 1. writeback - the client's shadow takes the bytes, // 2. unmap - the read mapping goes away, // 3. serial stamp- syncedChangeSerial catches up with the record, so the next @@ -1900,7 +1901,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // The seventh slot table. A process-lifetime global, like the other six, so it links - // itself into its own holder list from its own constructor with no initialisation + // itself into its own holder list from its own constructor with no initialization // order question to answer (SlotTables.h). BackendBufferResourceTable g_backendBufferResources; @@ -2112,7 +2113,7 @@ namespace MobileGL::MG_Backend::DirectGLES { #if MOBILEGL_BUILD_DISAGGREGATED // P11 B2: the T0 half of the deferred-release drain, run right after it at both sync // points (ProcessDeferredBufferReleases itself moves verbatim, G5). Retired imports whose - // fence signalled let go of their AHardwareBuffer; a deferred T0 destroy is retired once + // fence signaled let go of their AHardwareBuffer; a deferred T0 destroy is retired once // the drain deleted its id (the fence then follows the delete) or its context is gone. void ProcessDeferredT0Retires() { if (!g_t0Retired.empty()) SweepT0Retired(false); @@ -2309,7 +2310,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const SizeT poolSize = ResourceWidthOf(res); // The pool DECISION is the legacy one, unchanged: extent and residence only. // An earlier cut added "and a shadow base was recorded", which silently stopped - // a buffer recycling pool ids - a change to D-F's pool behaviour, not to "the + // a buffer recycling pool ids - a change to D-F's pool behavior, not to "the // source of bytes" the conversion is allowed to move, and one that moves // AcquireFromPool call counts StreamedArenaScenario observes. const Uint reused = (poolSize > 0 && !resource->persistentMapped) ? AcquireFromPool(poolSize) : 0; diff --git a/MobileGL/MG_Backend/DirectGLES/ManagersFramebuffers.cpp b/MobileGL/MG_Backend/DirectGLES/ManagersFramebuffers.cpp index 35ccd317..1a0a4692 100644 --- a/MobileGL/MG_Backend/DirectGLES/ManagersFramebuffers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/ManagersFramebuffers.cpp @@ -146,7 +146,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // re-issued is invalidated too - the attachment versions below, and under // MOBILEGL_PIPE_PUSH the record memos stamped at the end of this function - so the // next sync re-attaches all non-empty attachments at their identity points AND - // (see SyncToBackend's attachment loop) detaches any colour point whose frontend owner + // (see SyncToBackend's attachment loop) detaches any color point whose frontend owner // is empty. Without that detach a stale image would survive under a point the table now // claims for a different, empty attachment. for (Uint i = 0; i < MAX_COLOR_ATTACHMENT_SLOTS; ++i) { @@ -250,7 +250,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // kMGPipeSurfaceNoTextureTarget on a texture point is a seam defect - refused loudly and // answered false, never guessed. False is the safe direction for all four: the mask // turns an emulation ON, and an emulation that does not run leaves the driver's own - // (correct-for-the-real-format) behaviour, while one that runs on the wrong buffer + // (correct-for-the-real-format) behavior, while one that runs on the wrong buffer // clamps or overwrites texels the application wrote. static Bool PushedSurfaceTextureTarget(const MG_Pipe::MGPSurface& surface, TextureTarget* out) { if (surface.TextureTarget == MG_Pipe::kMGPipeSurfaceNoTextureTarget) { @@ -314,7 +314,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The record's surface for an attachment POINT, or null when this record does not // describe that point at all. MGPFramebufferState carries Color[8] + Depth + Stencil // (D-C1), which is every point a framebuffer can hold on the handle arm: D-C3 refuses - // bit 9 outright on a driver reporting more than 8 colour attachments, and the + // bit 9 outright on a driver reporting more than 8 color attachments, and the // FRONT/BACK points belong to the DEFAULT framebuffer, which has no twin at all. const MG_Pipe::MGPSurface* PushedSurfaceForAttachment(const MG_Pipe::MGPFramebufferState& record, FramebufferAttachmentType point) { @@ -465,7 +465,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // an object the apply thread was handed. // // P5e (fix1, ID-81): arm-selected for the texture arm's reason, and here it is a - // BEHAVIOUR difference even though the by-handle body dereferences nothing: the + // BEHAVIOR difference even though the by-handle body dereferences nothing: the // object form reports a refused allocation to the application through the live // GLContext (RecordError) and the by-handle form deliberately does not, because // under a transport there is no application on this side to report it to. On the @@ -483,7 +483,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // The read attachment's storage carries an alpha channel its frontend format does not - // (the three-channel colour-renderable widening). GL answers such a read with 1.0, but + // (the three-channel color-renderable widening). GL answers such a read with 1.0, but // the storage holds whatever the draw wrote there, so the readback has to overwrite it. Bool IsAlphaWidenedFallbackReadAttachment() { const auto* record = MG_Pipe::MGPipeApplier().ReadFramebuffer(); @@ -552,7 +552,7 @@ namespace MobileGL::MG_Backend::DirectGLES { void BackendFramebufferObject::ApplyReadBufferFromRecord(const MG_Pipe::MGPFramebufferState& record, Uint glNameForDiag) { // D-C1 makes the NULL Res the spelling of "no attachment" and c0c's - // kMGPipeSurfaceKindNone makes Kind agree with it on a zero-initialised record. + // kMGPipeSurfaceKindNone makes Kind agree with it on a zero-initialized record. // Res stays the test - it is the one D-C1 fixes - and Kind is CROSS-CHECKED // rather than consulted: the two are one statement the emitter has to make // twice, and a record where they disagree is a seam defect, not an empty point. @@ -569,7 +569,7 @@ namespace MobileGL::MG_Backend::DirectGLES { FramebufferAttachmentType pushedReadBuf = FramebufferAttachmentType::None; if (!readSurfaceEmpty) { // EVERY FIELD THAT IDENTIFIES THE IMAGE, not the three v1 compared (m-4). - // The same image legally sits at two colour points - a layered attachment of + // The same image legally sits at two color points - a layered attachment of // one array and a single slice of it are different surfaces of one Res - so a // partial comparison resolves to the lower index and the refusal branch below // ("refusing to guess") would then be doing part of the guessing itself. @@ -590,7 +590,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } if (!matched) { MGLOG_E_ONCE("MGPipe: framebuffer %u's resolved read surface {%u, %u} matches no " - "colour attachment of its own record - refusing to guess a read " + "color attachment of its own record - refusing to guess a read " "buffer", glNameForDiag, record.ReadSurface.Res.Slot, record.ReadSurface.Res.Gen); return; @@ -659,7 +659,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // fire the table would disagree with the glDrawBuffers the caller already issued, // which is the exact non-injectivity this table exists to remove. MOBILEGL_ASSERT(a < slotCount && !assigned[a], - "Draw buffer %u names colour attachment %u which is out of range or duplicated.", s, a); + "Draw buffer %u names color attachment %u which is out of range or duplicated.", s, a); if (a >= slotCount || assigned[a]) { continue; } @@ -890,7 +890,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // 3. The attachments. Three gates, and the key is the object's rather than the // binding's: idGenerationMoved ("I re-minted a driver id, so a point may hold a - // dead one"), attachmentPointsMoved ("the colour permutation moved, so a point + // dead one"), attachmentPointsMoved ("the color permutation moved, so a point // whose record did not change still has to be re-issued") and the record hash. // NOT m_syncedRecordHashes: the per-target array is the object arm's re-arm // trigger, and the points written below belong to the driver FBO rather than to @@ -910,7 +910,7 @@ namespace MobileGL::MG_Backend::DirectGLES { const Bool empty = surface.Kind == MG_Pipe::kMGPipeSurfaceKindNone || MG_Pipe::MGPipeHandleIsNull(surface.Res); // The detach that keeps m_backendColorSlots a permutation of the PHYSICAL - // layout: a colour point whose record says empty must not keep the previous + // layout: a color point whose record says empty must not keep the previous // owner's image, or glReadBuffer returns it. Bounded by the driver's cap, // because GL_COLOR_ATTACHMENTn above it is INVALID_ENUM. if (isColorPoint && empty) { @@ -979,12 +979,12 @@ namespace MobileGL::MG_Backend::DirectGLES { } GLenum BackendFramebufferObject::GetBackendAttachmentType(FramebufferAttachmentType frontendAtt) const { - // Only colour attachments are ever relocated; depth/stencil, the default framebuffer's + // Only color attachments are ever relocated; depth/stencil, the default framebuffer's // FRONT/BACK names and None map straight through. if (frontendAtt < FramebufferAttachmentType::Color0 || frontendAtt > FramebufferAttachmentType::Color31) { return MG_Util::ConvertFramebufferAttachmentTypeToGLEnum(frontendAtt); } - // The table is a permutation of the backend colour points, so this is the one point that + // The table is a permutation of the backend color points, so this is the one point that // owns this attachment. Searching the draw-buffer array instead returned the identity // point for every attachment that was not a draw buffer - which is exactly the point a // relocated draw buffer had just taken over, so COLOR_ATTACHMENT0 read back the image of diff --git a/MobileGL/MG_Backend/DirectGLES/ManagersInternal.h b/MobileGL/MG_Backend/DirectGLES/ManagersInternal.h index afc311c9..c6df6820 100644 --- a/MobileGL/MG_Backend/DirectGLES/ManagersInternal.h +++ b/MobileGL/MG_Backend/DirectGLES/ManagersInternal.h @@ -237,7 +237,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The four hostBytes sites read the same in both builds. The non-split expansion is the // ORIGINAL EXPRESSION, character for character - `raw - offset` - so a push or verify build -// compiles exactly what it compiled before R-11 and the split arm is the only new behaviour. +// compiles exactly what it compiled before R-11 and the split arm is the only new behavior. #define MGL_SERVER_STAGED_ADOPT(res, width, bytes, offset, size) \ ServerStaged().Adopt(&(res), (width), (bytes), (offset), (size)) #define MGL_SERVER_STAGED_REQUIRE_PENDING(res, base, frontendSize, site) \ @@ -476,7 +476,7 @@ namespace MobileGL::MG_Backend::DirectGLES { namespace { // One shape for all five, so a kind cannot grow a different liveness rule than its - // neighbours: index the applier's own dense table, refuse a slot it has not grown to, + // neighbors: index the applier's own dense table, refuse a slot it has not grown to, // refuse a record that is not Live, and refuse a generation that has moved on under // the caller. The last of the three is the one that matters: a stale handle resolving // to its successor's record is how a twin ends up describing another object's storage. diff --git a/MobileGL/MG_Backend/DirectGLES/ManagersPrograms.cpp b/MobileGL/MG_Backend/DirectGLES/ManagersPrograms.cpp index 061b0c1a..443e2326 100644 --- a/MobileGL/MG_Backend/DirectGLES/ManagersPrograms.cpp +++ b/MobileGL/MG_Backend/DirectGLES/ManagersPrograms.cpp @@ -417,7 +417,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // every draw of every program with an override would rebuild. Taking the client's number // verbatim removes that coupling: there is one authority, and the twin's stamp and the // clean clause read the same field. The monolith arm's source carries the answer of the - // function this replaces, computed from the frontend map, so its behaviour is unchanged. + // function this replaces, computed from the frontend map, so its behavior is unchanged. Uint64 ComputeShaderStorageBlockBindingSignature(const ProgramBuildSource& src) { return src.StorageOverrideSignature; } @@ -1022,7 +1022,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // GL 4.6 core table 23.53 requires GL_MAX_SAMPLES >= 4, so every multisample // ceiling MobileGL advertises is floored to 4 no matter what the ES driver - // reports - but the realised allocation cannot be, and + // reports - but the realized allocation cannot be, and // ClampSamplesToBackendSupport quietly gives an integer or depth multisample // texture the ONE sample Adreno and Mali actually support for it. A shader // written against the advertised ceiling then fetches a sample that storage does @@ -1051,7 +1051,7 @@ namespace MobileGL::MG_Backend::DirectGLES { *effectiveSpirv, splitArrayInputSpirv, enableSpirvValidation) && !splitArrayInputSpirv.empty() && splitArrayInputSpirv != *effectiveSpirv) { // Only when the pass ACTUALLY split something: the optimizer hands back a - // re-serialised copy either way, and that round trip is not free - it cost the + // re-serialized copy either way, and that round trip is not free - it cost the // minecraft-1.21.1-neoforge-create-indirect-in-world-align1024 retrace 0.15 SSIM. effectiveSpirv = &splitArrayInputSpirv; } @@ -1095,11 +1095,11 @@ namespace MobileGL::MG_Backend::DirectGLES { // Left outside, a second program sharing this stage's key would be served ESSL // with the blocks un-renamed and the repair would silently stop working - the // same trap SetAtomicCounterBlockBindings sets one screen down. - // * AT THIS POSITION, because moving a SPIR-V pass in a chain is a behavioural + // * AT THIS POSITION, because moving a SPIR-V pass in a chain is a behavioral // change, and this one arrived device-verified on Mali. Hoisting it above the // cache probe instead would have needed no key material at all (the rename would // already be in the module bytes the key hashes) and was rejected for that - // reason: it reorders the chain, and it would re-serialise the module on every + // reason: it reorders the chain, and it would re-serialize the module on every // build including the ones the memo is there to make free. // Its two rename maps are therefore KEY MATERIAL - see the caller. Vector uniquifiedIoBlockSpirv; @@ -1333,7 +1333,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The caller arms the two directions; both are false unless the driver POST // measured the defect AND this program has a stage that can hit it. Adopted only // when this stage really had a located block, for the reason the array-input split - // documents: the optimizer hands back a re-serialised copy either way. + // documents: the optimizer hands back a re-serialized copy either way. // // LAST IN THE CHAIN, and that position is load-bearing. Vulkan SPIR-V REQUIRES a // Location on every user-defined Input/Output variable @@ -1385,7 +1385,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // ES fixes a storage block's binding at link from its layout(binding=) qualifier // and has no glShaderStorageBlockBinding to move it afterwards, so a rebinding - // can only be honoured by printing it INTO the qualifier. Rewriting the Binding + // can only be honored by printing it INTO the qualifier. Rewriting the Binding // decoration before SPIRV-Cross emits is what does that; RemoveLayoutBinding // then deliberately preserves the qualifier for `buffer` declarations. if (!storageBlockBindingOverrides.empty()) { // empty for almost every program @@ -1516,12 +1516,12 @@ namespace MobileGL::MG_Backend::DirectGLES { return; } - // Mirrored from the neighbours rather than fixed: whether SPIRV-Cross redeclares + // Mirrored from the neighbors rather than fixed: whether SPIRV-Cross redeclares // gl_PerVertex, and with which members, depends on what the application's shaders // touched, and a synthesized stage that redeclares a DIFFERENT shape than the stage // it feeds is an ES link error against a program with no other problem. gl_in copies // the vertex stage's OUT block (that is what arrives) and gl_out the evaluation - // stage's IN block (that is what is expected). A neighbour that redeclared nothing + // stage's IN block (that is what is expected). A neighbor that redeclared nothing // yields an empty list, which leaves the driver's own built-in declaration in place - // which is exactly what matching it requires. const String inMembers = ExtractPerVertexBlockMembers(vertexStageEssl, /*input=*/false).value_or(String()); @@ -1531,7 +1531,7 @@ namespace MobileGL::MG_Backend::DirectGLES { String source = BuildPassthroughTessControlEssl(ResolveBackendEsslVersion(), patchVertices, inMembers, outMembers, m_passthroughTessControlOuterLevel, m_passthroughTessControlInnerLevel); - // The mirrored member lists can carry gl_PointSize - the neighbour stage declared it, + // The mirrored member lists can carry gl_PointSize - the neighbor stage declared it, // so matching it is the whole point - and a redeclaration is exactly as illegal as a // reference in ESSL without the extension. Same directive, same never-speculative // rule as the per-stage loop; a driver with neither spelling gets nothing added and @@ -1543,7 +1543,7 @@ namespace MobileGL::MG_Backend::DirectGLES { : nullptr; source = RequestPointSizeExtension(Move(source), passthroughPointSizeExtension); // Same for gl_ClipDistance/gl_CullDistance mirrored out of a vertex stage that - // writes them: the neighbour could only compile with the extension, so it exists. + // writes them: the neighbor could only compile with the extension, so it exists. source = RequestClipCullDistanceExtension(Move(source)); const GLuint backendShaderId = g_GLESFuncs.glCreateShader(GL_TESS_CONTROL_SHADER); @@ -1608,7 +1608,7 @@ namespace MobileGL::MG_Backend::DirectGLES { m_frontendProgramId = src.GetExternalIndex(); // GetSpirvStatus() as well as GetLinkStatus(): a program whose phase-B job was - // cancelled (teardown) or whose optimizer run failed is fully linked and fully + // canceled (teardown) or whose optimizer run failed is fully linked and fully // queryable, but has no SPIR-V to build a driver program out of. GL cannot retract // a LINK_STATUS it already reported true, so "linked but not drawable" is the // answer, and this is where the ES backend expresses it. @@ -1773,7 +1773,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // // The repair is a rename keyed on the PRODUCING stage, planned here and applied // per stage below so a producer and its consumer keep naming the same block. - // Gated twice over, because a re-serialised module is not free (it cost the + // Gated twice over, because a re-serialized module is not free (it cost the // create-indirect retrace 0.15 SSIM the first time the array-input split missed // its gate; the case is now // minecraft-1.21.1-neoforge-create-indirect-in-world-align1024): only a tessellation @@ -1890,7 +1890,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // an output nothing can read. That is not merely useless: in a separable program // pipeline the fragment stage lives in a DIFFERENT program, which never saw this // build and cannot be given a gate, so promoting there would hang an unmatched - // varying off a program to buy nothing. Both cases keep the pre-emulation behaviour, + // varying off a program to buy nothing. Both cases keep the pre-emulation behavior, // which is what a program with no fragment stage had anyway. const Bool programHasFragmentStage = std::find(linkedStages.begin(), linkedStages.end(), ShaderStage::Fragment) != linkedStages.end(); @@ -1974,7 +1974,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // KEYING ON THE RESOLVED MAPS rather than on what they were derived from // (collidingIoBlockNames, declaredIoBlockNames, stagePipelineIndices, this // stage's index) is deliberate: the maps ARE the pass's arguments, so they are - // exactly as fine as the pass's behaviour and no finer. Two programs whose + // exactly as fine as the pass's behavior and no finer. Two programs whose // collision plans differ but whose maps for THIS stage come out identical really // do produce the same ESSL and should share the entry. // @@ -2225,7 +2225,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // * AFTER RebindImageUniformsToFrontendUnits, so the binding it copies onto // both halves of a split image is already the frontend texture unit (and so // that pass never has to reason about the alias it introduces); - // * BEFORE RemoveLayoutBinding, whose keepBindingRegex recognises an image + // * BEFORE RemoveLayoutBinding, whose keepBindingRegex recognizes an image // declaration and preserves its binding - an image unit cannot be set from // the API in ES, so the qualifier is the only binding mechanism there is, // and both halves of the pair have to still be carrying theirs when it runs. @@ -2639,7 +2639,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // arm - and building from an empty reflection would produce a program with no // uniforms and no modules, i.e. a black screen with no marker anywhere. The // create's own trip wire already refuses a record that declares no blobs AND - // carries no artefacts (PipeApply.cpp); this is the same statement one level later, + // carries no artifacts (PipeApply.cpp); this is the same statement one level later, // where the twin can name the handle. if (!record->Archive) { MGLOG_E_ONCE("MGPipe: shader CSO {%u, %u} carries no server-owned archive; its " @@ -2668,7 +2668,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // one location per ELEMENT, so a caller walking locations sees the same name // repeatedly; this turns it back into "goku[k]". Anything that is not an array // (or whose base location cannot be resolved) comes back unchanged, so the only - // behaviour that moves is the array case. + // behavior that moves is the array case. String SubscriptUniformNameForElement(const ProgramBuildSource& program, const String& name, Uint location) { if (name.size() < 3 || name.compare(name.size() - 3, 3, "[0]") != 0) return name; @@ -2794,7 +2794,7 @@ namespace MobileGL::MG_Backend::DirectGLES { if (!m_backendProgramUsable) { // Every draw made with this program renders nothing and raises no GL error, so // without this line the only symptom is a framebuffer that kept its clear - // colour. Latched: the early return above only dedupes CONSECUTIVE binds, so an + // color. Latched: the early return above only dedupes CONSECUTIVE binds, so an // app alternating a healthy and a broken program would otherwise log every // single draw. Parked at MGLOG_I until the level ordering was fixed. MGLOG_E_ONCE("Backend program for GL program %u is unusable (a shader failed to transpile, " diff --git a/MobileGL/MG_Backend/DirectGLES/ManagersSamplers.cpp b/MobileGL/MG_Backend/DirectGLES/ManagersSamplers.cpp index 03fb1d8c..59f23213 100644 --- a/MobileGL/MG_Backend/DirectGLES/ManagersSamplers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/ManagersSamplers.cpp @@ -168,8 +168,8 @@ namespace MobileGL::MG_Backend::DirectGLES { m_cacheSamplerParameters.borderColorI != samplerParams.borderColorI || m_cacheSamplerParameters.borderColorUI != samplerParams.borderColorUI || m_cacheSamplerParameters.borderColorForm != samplerParams.borderColorForm) { - // Same gate as the texture-side border colour above, and the same reason for - // branching on the form: an integer border colour must reach the driver through + // Same gate as the texture-side border color above, and the same reason for + // branching on the form: an integer border color must reach the driver through // glSamplerParameterIiv/Iuiv or an integer sampler reads the float's bit pattern // back instead of the value. if (g_GLESCapabilities.SupportsTextureBorderClamp) { diff --git a/MobileGL/MG_Backend/DirectGLES/ManagersTextureSync.cpp b/MobileGL/MG_Backend/DirectGLES/ManagersTextureSync.cpp index bfc87db4..057a75b3 100644 --- a/MobileGL/MG_Backend/DirectGLES/ManagersTextureSync.cpp +++ b/MobileGL/MG_Backend/DirectGLES/ManagersTextureSync.cpp @@ -212,7 +212,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } } - // A three-channel format widened to four to keep a colour attachment renderable (see + // A three-channel format widened to four to keep a color attachment renderable (see // NormalizePixelFormat) is described to the driver as a four-component transfer, so the // three-component client data has to be repacked with an alpha of 1.0 - otherwise the // driver walks three texels' worth of data per four-texel row and the image shears. @@ -467,7 +467,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // The transfer half of the image-format widening: an image-bindable texture whose ES // storage was widened to a core carrier is described to the driver as a four-component // transfer, so its narrower client data has to be repacked the same way the three-channel - // colour-renderable widening repacks its own. + // color-renderable widening repacks its own. // // Three shapes, because the carriers come in three kinds. Most of them keep the frontend // format's component TYPE and only add channels, so padding the shadow out to four @@ -836,7 +836,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // consume is a swap-and-pop - so every one of them is taken, used and dropped // inside one level's iteration, and never held across a consume. if (pushedStorage != nullptr) { - // THE METADATA RESPECIFY, HONOURED (ID-18 M4, review M-2). BindMask and + // THE METADATA RESPECIFY, HONORED (ID-18 M4, review M-2). BindMask and // ImageBindableHint are STICKY facts the client discovers AFTER allocation - a // texture first bound as a shader image - and an IMMUTABLE texture never has a // later redefinition to carry them, so they arrive on a respecify that restates @@ -868,7 +868,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // ONE compare replaces the whole cheap-gate trio AND the content version. The // applier bumps Serial on every respecify and every sub-data it applies to this // resource, which is exactly the union those four keys covered - without the - // coarse behaviour the sampling-resolution generation had, where any texture's + // coarse behavior the sampling-resolution generation had, where any texture's // shape churn re-opened every other texture's gate. // // The pending set is the second half and it is not redundant: a previous sync @@ -2086,7 +2086,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // transport-gated - safe by a chain rather than by its own statement, which // is exactly the shape that cost the monolith arm 137 scenarios. Under a // transport the conjunct is already implied by `pushedStorage != nullptr`, so - // this changes no behaviour and closes no door; it says the thing instead of + // this changes no behavior and closes no door; it says the thing instead of // depending on it. const Bool texBufferByRecord = pushedStorage != nullptr && MGB_TEXTURE_HANDLE_ARM_OFF(*this) == false; static const SharedPtr kNoFrontendBuffer{}; diff --git a/MobileGL/MG_Backend/DirectGLES/ManagersTextures.cpp b/MobileGL/MG_Backend/DirectGLES/ManagersTextures.cpp index 04d531d9..8a05bec9 100644 --- a/MobileGL/MG_Backend/DirectGLES/ManagersTextures.cpp +++ b/MobileGL/MG_Backend/DirectGLES/ManagersTextures.cpp @@ -461,7 +461,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // otherwise still claim those values are in force and SyncTextureParamsToBackend // would skip the whole pass on the unchanged params version, leaving the driver // texture at defaults for the rest of its life. Latent for swizzle, LOD range and - // border colour long before GL_DEPTH_STENCIL_TEXTURE_MODE joined them; the mode + // border color long before GL_DEPTH_STENCIL_TEXTURE_MODE joined them; the mode // makes it visible because falling back to the default silently samples the wrong // aspect rather than merely mis-filtering. m_cacheLodRange = {0, 1000}; @@ -835,7 +835,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // NO set_texture_params HAS BEEN APPLIED FOR THIS TEXTURE YET, which is not the same // thing as a malformed one and must not be read as one. ParamsSerial is the // applier's own "have I ever stored a params record here" (it is bumped on every - // set_texture_params and starts at 0), and Params is value-initialised beside it - + // set_texture_params and starts at 0), and Params is value-initialized beside it - // so on a texture the application has never given a parameter to, BuiltinSampler is // null because the record was never written, not because a client wrote a null. // There is nothing to push in that state; SyncTextureParamsToBackend's own gate @@ -912,7 +912,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // P4a (D-E1): the fifteen sampler values are SAMPLER state (GL 4.6 table 23.18) and // Espryt pushes them with glTexParameter* onto the TEXTURE rather than with - // glBindSampler onto the unit - behaviour P4a preserves exactly. What changes is + // glBindSampler onto the unit - behavior P4a preserves exactly. What changes is // where the values and the "did they move" answer come from. // // The whole arm choice is a preprocessor #if/#else rather than a runtime branch @@ -1055,7 +1055,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // independent of any binding - that is what closes D-E3's gap, where a texture that is // only a READ-framebuffer attachment reaches SyncMipmapsToBackend and nothing else. The // FORMAT comes from the descriptor beside them, and the BORDER comes from the built-in - // sampler's CSO (D-F4), because a border colour is sampler state. + // sampler's CSO (D-F4), because a border color is sampler state. #define MGB_TEXPARAM_LEVEL_RANGE \ (pushedRecord != nullptr ? UintVec2{static_cast(pushedRecord->Params.BaseLevel), \ static_cast(pushedRecord->Params.MaxLevel)} \ @@ -1117,7 +1117,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Bool borderColorReadable = true; pushedRecord = ResolvePushedTextureParams(stateTextureObject); if (pushedRecord == nullptr) return; - // D-F4: the border colour is SAMPLER state (GL 4.6 table 23.18) and lives on the + // D-F4: the border color is SAMPLER state (GL 4.6 table 23.18) and lives on the // built-in sampler's CSO, not on MGPTextureParams - P4a deliberately does not // put SamplerParameters on the wire twice. All FOUR comparands (float, int, // uint, form) still cross and are still all compared below, because two integer @@ -1129,7 +1129,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } else { borderColorReadable = false; MGLOG_E_ONCE("MGPipe: texture %u's built-in sampler CSO {%u, %u} has no applier " - "record, so its border colour cannot be pushed", + "record, so its border color cannot be pushed", TextureDiagName(stateTextureObject, pushedRecord), pushedRecord->Params.BuiltinSampler.Slot, pushedRecord->Params.BuiltinSampler.Gen); } @@ -1185,7 +1185,7 @@ namespace MobileGL::MG_Backend::DirectGLES { MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); - // A three-channel format widened to four to keep the image colour-renderable (see + // A three-channel format widened to four to keep the image color-renderable (see // NormalizePixelFormat) gains an alpha channel the frontend format does not have, and // whatever the draw that filled it wrote there is not what GL would report: a format // without alpha reads back as 1.0. Answer the ALPHA swizzle source with ONE so the @@ -1246,7 +1246,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // GL_TEXTURE_BORDER_COLOR needs ES 3.2 or EXT/OES_texture_border_clamp; on a driver // without it every such call is INVALID_ENUM, so the parameter is simply not synced. // - // The FORM has to be forwarded along with the value. A border colour set through + // The FORM has to be forwarded along with the value. A border color set through // glTexParameterIiv/Iuiv is an integer one, and an isampler2D/usampler2D fetch of the // border returns whatever the driver's integer border register holds - so pushing it // through glTexParameterfv handed the driver float 255.0 and the shader read back @@ -1259,7 +1259,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // leave the driver holding the first value forever. // m-3: GATED, because on the handle arm an unreadable border means the CSO record is // missing and the block below is skipped with the refusal already named - so v1's - // unconditional initialiser was a live frontend read on a switched-over path whose + // unconditional initializer was a live frontend read on a switched-over path whose // value nothing then used. The value a skipped block sees is the cache's own, which // cannot make the condition true. const auto borderColorForm = borderColorReadable ? MGB_TEXPARAM_BORDER_FORM : m_cacheBorderColorForm; diff --git a/MobileGL/MG_Backend/DirectGLES/ManagersVertexArrays.cpp b/MobileGL/MG_Backend/DirectGLES/ManagersVertexArrays.cpp index 45bafab6..0f17c344 100644 --- a/MobileGL/MG_Backend/DirectGLES/ManagersVertexArrays.cpp +++ b/MobileGL/MG_Backend/DirectGLES/ManagersVertexArrays.cpp @@ -597,7 +597,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // already returned. A buffers-only walk leaves the flags as they are (above). if (!buffersOnly) HostSetEnabled(attribIndex, attrib.Enabled != 0); - // The fp64 narrowing, verbatim in behaviour including the Adreno workaround: + // The fp64 narrowing, verbatim in behavior including the Adreno workaround: // when no float32 stream can be built the array is DISABLED rather than left // enabled with no pointer, which is what the driver turns into a SIGSEGV inside // the next draw (KHR-GL43.vertex_attrib_binding.basic-input-case4). IsLong is @@ -981,7 +981,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // object - that absence is the design, not a gap in it (ARCHITECTURE.md 4.2). The // two ways to keep the site here would each break something D-N or D-J protects: a // handle -> object map is the very thing the split removes, and pulling the bytes - // eagerly on the client at every draw is new behaviour and new cost. + // eagerly on the client at every draw is new behavior and new cost. // // SO THE DEVIATION IS DECLARED, WITH ITS BLAST RADIUS. Under the default mask a // 64-bit vertex array whose SOURCE buffer was written by a shader and not yet pulled @@ -1104,7 +1104,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // source type and `normalized` (GL accepts BGRA only normalized, and a packed type's // signedness is the type's own). The narrowed stream is float32, and `normalized` is // deliberately GL_FALSE there rather than attrib.Normalized: GL ignores it for - // floating-point array types, and honouring it would scale the fetched values. + // floating-point array types, and honoring it would scale the fetched values. const GLint convertedSize = bgra ? 4 : static_cast(attrib.Size); const GLenum convertedType = bgra ? MG_Util::ConvertDataTypeToGLEnum(sourceType) : GL_FLOAT; const GLboolean convertedNormalized = (bgra && attrib.Normalized) ? GL_TRUE : GL_FALSE; diff --git a/MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp b/MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp index 3bb0a05f..4c7209de 100644 --- a/MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp +++ b/MobileGL/MG_Backend/DirectGLES/MultiDraw.cpp @@ -87,7 +87,7 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl { // The flattening dispatch is one invocation per output index. ES 3.1 only // guarantees 65535 work groups per dimension, and exceeding it makes // glDispatchCompute an INVALID_VALUE no-op - which would leave the draw reading an - // uninitialised index buffer rather than failing visibly. Cap the tier there + // uninitialized index buffer rather than failing visibly. Cap the tier there // instead of querying: 4.19M indices is far past any real multi-draw batch, and // beyond it the per-sub-draw tiers are the better answer anyway. constexpr SizeT kComputeWorkGroupSize = 64; @@ -239,7 +239,7 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl { // ---- P5e (ra2), ID-136: THE SEAT THIS FILE'S OWN RULE HAD MISSED ------------------- // // This was the LAST unguarded frontend read on the multi-draw apply path, and it sat - // twenty lines above the function that retired its neighbour. It asked + // twenty lines above the function that retired its neighbor. It asked // `gPipeInputs->GetBufferBindingSlot(BufferTarget::DrawIndirect)` and then // `EnsureBufferResource()` - a registry lookup keyed by the client's // identity, which is §4.4's rule and not only the allocator's. Under run-ahead that is @@ -524,7 +524,7 @@ namespace MobileGL::MG_Backend::DirectGLES::MultiDrawImpl { std::memcpy(&value, source + i * 4, sizeof(value)); break; } - // Unsigned wraparound is the defined behaviour for a negative base vertex. + // Unsigned wraparound is the defined behavior for a negative base vertex. out[i] = (restartActive && value == restartSentinel) ? 0xFFFFFFFFu : value + baseVertexBits; } } @@ -789,7 +789,7 @@ void main() { } uint localIndex = outIndex - (low == 0u ? 0u : drawInfo[(low - 1u) * 3u + 2u]); - // Unsigned wraparound is the defined behaviour for a negative base vertex. No + // Unsigned wraparound is the defined behavior for a negative base vertex. No // restart sentinel handling: the tier declines outright while restart is enabled. flatIndices[outIndex] = ReadSourceIndex(localIndex + drawInfo[low * 3u]) + drawInfo[low * 3u + 1u]; } @@ -1072,7 +1072,7 @@ void main() { GLsizei drawcount, const GLint* basevertex) { if (drawcount <= 0 || !count || !indices) return; // Read before any GL work, because it decides the tier below: a desktop restart index - // the driver does not know about can only be honoured by the tier that rewrites the + // the driver does not know about can only be honored by the tier that rewrites the // index stream (see ResolveTierForBatch). A restart index this index type cannot hold // needs no rewrite at all - nothing can match it - but it does need the driver's own // fixed-index restart held off for the batch, which is what the scope below does. diff --git a/MobileGL/MG_Backend/DirectGLES/NarrowIntegerSeeds.cpp b/MobileGL/MG_Backend/DirectGLES/NarrowIntegerSeeds.cpp index e27b8370..36976d4f 100644 --- a/MobileGL/MG_Backend/DirectGLES/NarrowIntegerSeeds.cpp +++ b/MobileGL/MG_Backend/DirectGLES/NarrowIntegerSeeds.cpp @@ -169,7 +169,7 @@ namespace MobileGL::MG_Backend::DirectGLES { String PromoteNarrowIntegerWidthGlobals(String source) { for (const char* name : {kNarrowIntegerWidths8GlobalName, kNarrowIntegerWidths16GlobalName}) { - // The zero-initialised Private global is printed with or without a precision qualifier; + // The zero-initialized Private global is printed with or without a precision qualifier; // only a declaration starting its own line is the global itself. for (const char* prefix : {"highp uint ", "mediump uint ", "lowp uint ", "uint "}) { Bool promoted = false; diff --git a/MobileGL/MG_Backend/DirectGLES/SlotTables.h b/MobileGL/MG_Backend/DirectGLES/SlotTables.h index 066b0cb3..28bb882d 100644 --- a/MobileGL/MG_Backend/DirectGLES/SlotTables.h +++ b/MobileGL/MG_Backend/DirectGLES/SlotTables.h @@ -302,7 +302,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // THE CALLING THREAD'S BUCKET, not every bucket, and that is the semantic answer // rather than a shortcut: a caller walking twins is asking "which of the objects I // can see need this", and what it can see is its own share group. Every bucket in - // one process would walk a neighbour session's objects. + // one process would walk a neighbor session's objects. ForCallingThread().ForEachLive(fn); } // Every bucket, in one pass. The caller receives the key with the handle so it can tell @@ -479,7 +479,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // THE TWO DIRECTIONS ARE NOT SYMMETRIC. The handle arrived in a payload, so // `handle.Gen < entry.Gen` is a reachable input, and adopting it would destroy the INCUMBENT LIVE twin - a // driver buffer id, a persistent map, a pooled store, released by a defaulted destructor that issues no - // glDeleteBuffers and no pool enrolment - and then stamp the slot back to the dead resource's generation, + // glDeleteBuffers and no pool enrollment - and then stamp the slot back to the dead resource's generation, // after which the incumbent's own FindByHandle refuses it and it is silently handed a fresh, empty twin. // That is a leak AND a resource that loses its storage with no diagnostic, i.e. the shape commit d7655247 // fixed and the thing MGPipeHandle::Gen exists to prevent. So: forward is a recycle and resets the twin, @@ -725,9 +725,9 @@ namespace MobileGL::MG_Backend::DirectGLES { } // The holder list: intrusive and doubly linked, so registering and unregistering are - // two pointer writes with no allocation, and its head is a constant-initialised + // two pointer writes with no allocation, and its head is a constant-initialized // static - which is what lets the process-lifetime registry globals in Managers.cpp - // link themselves in from their own constructors with no initialisation-order + // link themselves in from their own constructors with no initialization-order // question to answer. Single-threaded, like every table it links (the tables live and // die on the context thread, as the notice they answer does). void LinkHolder() { diff --git a/MobileGL/MG_Backend/DirectGLES/Utils.cpp b/MobileGL/MG_Backend/DirectGLES/Utils.cpp index 5a4aafb8..1bac044b 100644 --- a/MobileGL/MG_Backend/DirectGLES/Utils.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Utils.cpp @@ -163,7 +163,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // namespace namespace TextureImpl { - // Every image that can back a colour attachment needs a colour-renderable storage format, + // Every image that can back a color attachment needs a color-renderable storage format, // and ES has no renderable three-channel format at all: a three-channel float fallback is // a legal ES texture but neither legal multisample storage nor a legal attachment, so // GL_RGB8_SNORM / GL_RGB16F / ... have to be widened to four channels for any of them. @@ -178,7 +178,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // allocating it byte for byte. // // Do NOT read that as "nothing changes off-device". Measured on llvmpipe 26.1.6 - // (the headless CI driver), an ES 3.2 GL_TEXTURE_2D colour attachment is COMPLETE for + // (the headless CI driver), an ES 3.2 GL_TEXTURE_2D color attachment is COMPLETE for // GL_RGB8 and GL_RGB16F but INCOMPLETE_ATTACHMENT for GL_RGB8_SNORM, GL_SRGB8 and every // RGB integer format, and UNSUPPORTED for GL_RGB32F. Those eight formats therefore DO // take the widened path on llvmpipe, which is where the retrace fixtures and the glcts @@ -798,7 +798,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // geometry STAGES core but leaves gl_PointSize out of their gl_PerVertex entirely, // and SPIRV-Cross - which only ever sees a SPIR-V BuiltIn PointSize decoration - // prints the identifier with no directive behind it. Same hard rule as the two - // neighbours: never emitted speculatively, because `#extension` on a name the driver + // neighbors: never emitted speculatively, because `#extension` on a name the driver // does not advertise is a compile error of its own. if (extensionName == nullptr || glslCode.find(extensionName) != String::npos) { return glslCode; @@ -831,7 +831,7 @@ namespace MobileGL::MG_Backend::DirectGLES { static const std::regex imageDeclRegex( R"((layout\s*\(([^)]*)\)\s*)?uniform\s+(?:(?:readonly|writeonly|coherent|volatile|restrict|highp|mediump|lowp)\s+)*[iu]?image[A-Za-z0-9]+\s+([A-Za-z_][A-Za-z0-9_]*)\s*(\[[^\]]*\])?\s*;)"); // Every image format spelling GLSL has, so a declaration that already carries one is - // recognised whatever it says - the caller's map is consulted only for declarations + // recognized whatever it says - the caller's map is consulted only for declarations // with NO format, never to override a written one. static const std::regex existingFormatRegex( R"(\b(rgba32f|rgba16f|rg32f|rg16f|r11f_g11f_b10f|r32f|r16f|rgba16|rgb10_a2|rg16|rg8|r16|r8|rgba16_snorm|rgba8_snorm|rg16_snorm|rg8_snorm|r16_snorm|r8_snorm|rgba32i|rgba16i|rgba8i|rg32i|rg16i|rg8i|r32i|r16i|r8i|rgba32ui|rgba16ui|rgba8ui|rgb10_a2ui|rg32ui|rg16ui|rg8ui|r32ui|r16ui|r8ui)\b)"); @@ -1124,7 +1124,7 @@ namespace MobileGL::MG_Backend::DirectGLES { source += "precision highp float;\n"; source += "precision highp int;\n"; source += "layout(vertices = " + std::to_string(patchVertices) + ") out;\n"; - // Mirrored, never invented. An empty member list means the neighbouring stage did not + // Mirrored, never invented. An empty member list means the neighboring stage did not // redeclare the block either, and the driver's own built-in declaration is then what // both sides agree on - redeclaring here would be the thing that broke the match. if (!inPerVertexMembers.empty()) { @@ -1783,7 +1783,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // // Nothing downstream reads these names: the two passes that key on the GL uniform // name (RebindImageUniformsToFrontendUnits, BakeImageFormatQualifiers) both run - // BEFORE this one, RemoveLayoutBinding recognises an image declaration by its TYPE + // BEFORE this one, RemoveLayoutBinding recognizes an image declaration by its TYPE // token, and CacheResourceLocations skips image uniforms outright because ES image // units come only from layout(binding=N). The declarations this pass LEAVES ALONE - // already readonly/writeonly in the source, or r32f/r32i/r32ui, which need no @@ -1825,7 +1825,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Both halves carry `coherent`; see BuildImageDeclaration. The // single-declaration cases below stay as they were - nothing aliases them, so // there is no visibility to restore and no reason to pay for the cache - // behaviour. + // behavior. edits.push_back({decl.declStart, decl.declLength, BuildImageDeclaration(decl, "readonly", decl.aliasName, /*forceCoherent=*/true) + diff --git a/MobileGL/MG_Backend/DirectGLES/Utils.h b/MobileGL/MG_Backend/DirectGLES/Utils.h index 039b60d5..3a780443 100644 --- a/MobileGL/MG_Backend/DirectGLES/Utils.h +++ b/MobileGL/MG_Backend/DirectGLES/Utils.h @@ -47,8 +47,8 @@ namespace MobileGL::MG_Backend::DirectGLES { } // namespace VertexArrayImpl namespace TextureImpl { - // Whether images on this format-capability target can back a colour attachment, and so - // need a colour-renderable storage format even when the frontend asked for a + // Whether images on this format-capability target can back a color attachment, and so + // need a color-renderable storage format even when the frontend asked for a // three-channel one ES never renders to. Shared by the capability probe (which passes the // capabilities it has just queried, before the globals are published) and by the // allocation path (which reads the active backend's), so the format the cache was probed @@ -74,7 +74,7 @@ namespace MobileGL::MG_Backend::DirectGLES { Bool ShouldUseCaveatTextureFormat(TextureInternalFormat internalFormat, TextureTarget target); // True when the format the image is actually created with has an alpha channel the - // frontend format does not (the three-channel colour-renderable widening). GL reads such + // frontend format does not (the three-channel color-renderable widening). GL reads such // a channel back as 1.0, so any swizzle source of ALPHA has to be answered with ONE and // any readback of the image has to overwrite the alpha the draw happened to leave there. Bool BackendTextureFormatAddsAlpha(TextureInternalFormat internalFormat, TextureTarget target); @@ -105,7 +105,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // // The widened triple REPLACES what GenerateTextureFormatInfo chose, including any // renderability substitution: an image that cannot be image-bound is useless whatever its - // attachment behaviour, so the image constraint wins. In practice that only bites + // attachment behavior, so the image constraint wins. In practice that only bites // RG8_SNORM/R8_SNORM on a driver without EXT_render_snorm, where the storage stays // signed-normalized instead of becoming the half float that fallback would have picked - // so an image-bound texture in one of those two formats is no longer attachable, and @@ -115,11 +115,11 @@ namespace MobileGL::MG_Backend::DirectGLES { // compiled at all, so nothing that works today is being given up. // // KNOWN GAP, for the same "all three layers move together" reason: a widened texture that - // is ALSO an FBO colour attachment gains one to three writable channels, and a draw into + // is ALSO an FBO color attachment gains one to three writable channels, and a draw into // it can leave values in channels GL says are 0 and 1. Sampling and imageLoad are covered // (the swizzle composition in SyncTextureParamsToBackend and the shader-side mask), but a // glReadPixels/glGetTexImage that asks for more channels than the frontend format has - // would see them. Closing it needs the per-draw-buffer colour mask the three-channel + // would see them. Closing it needs the per-draw-buffer color mask the three-channel // widening already carries (FramebufferImpl::g_alphaWidenedDrawBufferMask) generalized // from "alpha" to a channel count, which is its own change. // How the FRONTEND's CPU shadow for a widened format is laid out relative to the carrier's @@ -319,7 +319,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // Exists so BuildPassthroughTessControlEssl can MIRROR the stages it has to sit between // rather than guess at them. Whether SPIRV-Cross redeclares the built-in block, and with // which members, depends on what the application's shader touched; a synthesized stage - // that redeclares a different shape than its neighbours is an ES link error against a + // that redeclares a different shape than its neighbors is an ES link error against a // program that has no other problem. std::optional ExtractPerVertexBlockMembers(const String& essl, Bool input); // Moves the clip/cull distance OUTPUTS of a vertex, tessellation evaluation or geometry @@ -365,15 +365,15 @@ namespace MobileGL::MG_Backend::DirectGLES { // bound in its place, and every draw silently renders nothing. // // `inPerVertexMembers` / `outPerVertexMembers` are the member lists to redeclare gl_in - // and gl_out with - normally taken from the neighbouring stages' own emitted ESSL via + // and gl_out with - normally taken from the neighboring stages' own emitted ESSL via // ExtractPerVertexBlockMembers, and empty to leave the driver's built-in declaration - // alone, which is what matching a neighbour that did not redeclare requires. + // alone, which is what matching a neighbor that did not redeclare requires. // // All four outer levels and both inner levels are written unconditionally: writing a // level the evaluation stage's domain does not use is legal and ignored, and it saves // this from having to know the domain. They are the GL_PATCH_DEFAULT_OUTER_LEVEL / // GL_PATCH_DEFAULT_INNER_LEVEL state, baked in as literals - ES has no such state and no - // glPatchParameterfv to forward to, so compiling them in is the only way to honour them. + // glPatchParameterfv to forward to, so compiling them in is the only way to honor them. // That makes them part of what a built program is stale against, exactly as PATCH_VERTICES // is: see the staleness clause in DirectGLES.cpp's SyncCurrentProgram, which compares both. // @@ -524,7 +524,7 @@ namespace MobileGL::MG_Backend::DirectGLES { // suffix is the sampler's own name. constexpr const char* MS_SAMPLE_MAX_UNIFORM_PREFIX = "mg_msSampleMax_"; // The runtime half of ClampMultisampleFetchPass's deferDirectUnsignedFetches. A - // usampler2DMS[Array] reads integer colour textures, which the backend may allocate with + // usampler2DMS[Array] reads integer color textures, which the backend may allocate with // fewer samples than MobileGL advertises, AND the stencil aspect of multisample // depth/stencil textures, which it allocates under the (larger) depth ceiling - so no // single compile-time bound is right for both. Declares one diff --git a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp index 83273630..dc2d3a75 100644 --- a/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/BackendObject_DirectVulkan.cpp @@ -878,7 +878,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { E_GL_ARB_texture_rg, // GL_DEPTH_COMPONENT32F and GL_DEPTH32F_STENCIL8. E_GL_ARB_depth_buffer_float, - // The floating-point colour formats. Unlike the rest of this block this string DOES + // The floating-point color formats. Unlike the rest of this block this string DOES // gate CTS cases - KHR-GL4*.internalformat.texture2d.*{16f,32f} is keyed on it with no // core-version fallback, so eight cases per version list were NotSupported on formats // the backend has always had. @@ -895,7 +895,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // - multiple capture buffers per stream, gl_SkipComponents / gl_NextBuffer, the // indexed queries and glDrawTransformFeedbackStream (4.0); E_GL_ARB_transform_feedback3, - // - GL_RGB10_A2UI (3.3), GL_RGB9_E5 (3.0) and the integer colour formats (3.0); + // - GL_RGB10_A2UI (3.3), GL_RGB9_E5 (3.0) and the integer color formats (3.0); E_GL_ARB_texture_rgb10_a2ui, E_GL_EXT_texture_shared_exponent, E_GL_EXT_texture_integer, // - the eleven pipeline-statistics query targets (4.6). Accepted by glBeginQuery and // answered with GL_QUERY_COUNTER_BITS = 0, the spec's own "this counter is not @@ -941,7 +941,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // recorded trace can never cover: Iris and Sodium change their SUBMISSION SCHEDULE // the moment they see it - they enqueue whole pipeline batches and poll // GL_COMPLETION_STATUS_KHR instead of compiling one program at a time - so - // MOBILEGL_ASYNC_SHADER_COMPILE=0 has to withdraw the application-visible behaviour + // MOBILEGL_ASYNC_SHADER_COMPILE=0 has to withdraw the application-visible behavior // change as well as the threading, or the kill switch would only be half a switch. if (MG_Util::Async::AsyncShaderCompileEnabled()) { extensions.push_back(E_GL_KHR_parallel_shader_compile); diff --git a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp index 2887105a..355701fa 100644 --- a/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/DirectVulkan.cpp @@ -238,7 +238,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // GetProgramResourceCache does it - over a multi-stage program with an arrayed SSBO and an // atomic-counter block, and asserts element-for-element equality with what the archive // published. That equivalence is what makes an #if here a build-time SELECTION rather than - // a behavioural fork, and it is the reason the case exists. + // a behavioral fork, and it is the reason the case exists. // // WHY AN #if AT ALL, AND WHAT IT COSTS. LinkArtifacts::storageBlocks is // MOBILEGL_BUILD_DISAGGREGATED-only, because one more Vector member changes the struct's @@ -263,7 +263,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { }; auto it = find(name); if (it == blocks.end()) { - // Archive names are normalised, so an arrayed block that GL enumerates per element + // Archive names are normalized, so an arrayed block that GL enumerates per element // - "B[0]", "B[1]" - is one entry here, spelled "B". Same second chance the cache // gave, for the same callers. const auto bracket = name.rfind('['); diff --git a/MobileGL/MG_Backend/DirectVulkan/MagmaSession.h b/MobileGL/MG_Backend/DirectVulkan/MagmaSession.h index b17f9fcc..fd2e8b1f 100644 --- a/MobileGL/MG_Backend/DirectVulkan/MagmaSession.h +++ b/MobileGL/MG_Backend/DirectVulkan/MagmaSession.h @@ -14,7 +14,7 @@ // // SessionLocal is that copy. It resolves through the CALLING THREAD's bound MagmaSession, and to // the process-wide default session on every thread nothing bound - which is the monolith, the client -// role and every unit case, i.e. exactly the old behaviour, on whatever thread the app renders from. +// role and every unit case, i.e. exactly the old behavior, on whatever thread the app renders from. // A served session's backend owns its MagmaSession and binds it on its apply thread (the only thread // that runs that session's backend), so the two never mix. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp index f916ac90..b5172584 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/FrameContext.cpp @@ -203,7 +203,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } // The barrier belongs in the frame's own recording. Bailing out because - // something was already recorded (the previous behaviour) dropped the + // something was already recorded (the previous behavior) dropped the // transition entirely for every frame that never ran a default-framebuffer // render pass - the only other thing that carries the image to // PRESENT_SRC_KHR, via that pass's finalLayout - so the swapchain image was diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/MagmaProgramSource.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/MagmaProgramSource.h index 2b0f3f28..9c396a2a 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/MagmaProgramSource.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/MagmaProgramSource.h @@ -165,7 +165,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // wire draw path entirely - this header no longer includes spirv_reflect.h at all. Uint GetShaderStorageBlockIndex(const String& name) const { const auto& blocks = Link().storageBlocks; - // The archive carries NORMALISED names (the array subscript stripped), because + // The archive carries NORMALIZED names (the array subscript stripped), because // that is the spelling SPIRV-Reflect's type_name gives and the spelling // ProgramFactory::ReflectLayout looks up. A caller that still holds a GL-style // "Foo[2]" gets the same second chance it always had. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp index 52c21ca4..a99b3c21 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.cpp @@ -452,7 +452,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // call was DEBUG-or-env gated and only logged, so an invalid module produced by a backend // transform went straight to vkCreateShaderModule. That is not a survivable outcome on // this hardware - Mali r54 SIGSEGVs building the pipeline instead of returning an error, - // the same "not a validating entry point" behaviour PipelineFactory already documents for + // the same "not a validating entry point" behavior PipelineFactory already documents for // vkCreateGraphicsPipelines - so the callers that feed the driver now act on it. // // This function does NOT log the failure at E any more. It used to, unlatched, on the @@ -972,7 +972,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // // Deliberately conservative - it answers "assume yes" for every shape it cannot read // exactly, because a false "no" would silently drop the clip-space fixup from a shader - // that does write gl_Position, while a false "yes" only reinstates the behaviour this + // that does write gl_Position, while a false "yes" only reinstates the behavior this // pass has always had. Scans every function rather than just the entry point's: a shader // that assigns gl_Position inside a helper is still a shader that writes it, and passing // the pointer to a call is a write as far as this can tell. @@ -1089,7 +1089,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (!FindPositionTarget(context(), &target)) return Status::SuccessWithoutChange; // Nothing to remap in a Position the shader never writes. Declining is not just - // an optimisation: the fixup is load-modify-store, so on an unwritten Position it + // an optimization: the fixup is load-modify-store, so on an unwritten Position it // converts "undefined, never written" into "written with whatever the load // returned", and the store is a reference to a variable the link-time sanitize // chain has already delisted from the entry-point interface. glslang emits the @@ -1165,7 +1165,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // ivec2(gl_FragCoord.xy)) into an image exactly the size of that viewport, so every // store fell outside the image and the test read back zeroes. // - // The rewrite redirects every read of the builtin to a Private copy initialised once at + // The rewrite redirects every read of the builtin to a Private copy initialized once at // entry, which is exact for all access forms (whole-vector loads, `.y` access chains, // OpCopyMemory) and leaves the builtin itself - and its decorations - untouched. class GlFragCoordYFlipPass final : public spvtools::opt::Pass { @@ -1233,7 +1233,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { {SPV_OPERAND_TYPE_STORAGE_CLASS, {static_cast(spv::StorageClass::Private)}}}); context()->AddGlobalValue(std::move(copyVar)); - // Redirect the reads BEFORE emitting the initialiser, so the initialiser's own + // Redirect the reads BEFORE emitting the initializer, so the initializer's own // load of the builtin is not rewritten into a load of the (still empty) copy. if (!RedirectReads(builtinVarId, copyVarId)) return Status::SuccessWithoutChange; @@ -1688,7 +1688,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { }; // Adreno 650 (driver 512.502) faults the GPU on an implicit-LOD sample of a full-screen - // colour render target: the texture unit's derivative path reads outside the image's + // color render target: the texture unit's derivative path reads outside the image's // allocation even though the sampler clamps LOD to 0 and the mapping is 1:1. MobileGL's // own default-framebuffer blit shader works around it with textureLod, but an // application's shader (Minecraft's blit.fsh is `texture(InSampler, texCoord)`) cannot be @@ -2146,7 +2146,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // GetOrCreateProgram's MOBILEGL_ASSERT(remapOk) as the only complaint, and // that assert compiles out above DEBUG - so a release build SILENTLY kept // glslang's per-stage auto-mapped binding numbers, skipping the cross-stage - // unification and the set->0 normalisation this function exists to do. A + // unification and the set->0 normalization this function exists to do. A // program with an image array plus any second descriptor got aliased // bindings out of that, and a DEBUG build trapped on the same program. // The refusal below is MGLOG_E and per-program-compile, so it reports every @@ -2989,7 +2989,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { MGLOG_D("ProgramFactory::ReflectLayout: %s array '%s' at binding %u spans %u descriptors but the " "reflection reserved fewer uniform locations for it (base=%d) - a multi-dimensional array " "is the usual cause, and MobileGL declines it rather than resolve elements onto a " - "neighbouring uniform", + "neighboring uniform", kindLabel, uniformName.c_str(), binding, count, baseLocation); outDeclined = true; } @@ -3530,7 +3530,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { "ProgramFactory::ReflectLayout, vkCreatePipelineLayout"); // Built here rather than where bindingKinds is sized: at that point the vector is only - // zero-initialised and the kinds are assigned further down, so a list built there would be + // zero-initialized and the kinds are assigned further down, so a list built there would be // empty. Ascending by construction because the index walks upward. entry.activeBindings.clear(); for (Uint32 binding = 0; binding < static_cast(entry.bindingKinds.size()); ++binding) { @@ -4128,7 +4128,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { ReflectPassthroughTessControlNeed(stages, moduleSpirvs, entry); ReflectLayout(program, moduleSpirvs, entry); // A failed remap means the modules kept glslang's per-stage auto-mapped binding numbers - - // no cross-stage unification, no set->0 normalisation - so the bindings this layout + // no cross-stage unification, no set->0 normalization - so the bindings this layout // describes are not the bindings the shader reads. That has to stop the program from // drawing, and until now nothing did: the MOBILEGL_ASSERT above compiles out of every // build past DEBUG, and RemapDescriptorBindingsForVulkan's own refusal message said so at @@ -4328,7 +4328,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // PATCH_DEFAULT_OUTER_LEVEL / PATCH_DEFAULT_INNER_LEVEL state. // // Those two levels are baked in as literals - Vulkan has no equivalent dynamic state, so - // compiling them in is the only way to honour glPatchParameterfv. That makes them part of + // compiling them in is the only way to honor glPatchParameterfv. That makes them part of // this module's identity: GetOrCreatePassthroughTessControlStage keys its cache on them, // and PipelineFactory hashes them into the pipeline key. The three must move together. // @@ -4344,7 +4344,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // this from having to know the domain. String source = "#version 450 core\n"; source += "layout(vertices = " + std::to_string(patchVertices) + ") out;\n"; - // gl_in and gl_out are redeclared to the exact gl_PerVertex the NEIGHBOURING EVALUATION + // gl_in and gl_out are redeclared to the exact gl_PerVertex the NEIGHBORING EVALUATION // STAGE carries, because Vulkan matches built-in interface blocks by their whole shape, // and the two obvious spellings are both wrong: // * narrowing the block to gl_Position alone makes the evaluation stage read a patch of diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.h index 8f1afcbf..07a3409a 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/ProgramFactory.h @@ -92,7 +92,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // The gl_PerVertex members a pass-through tessellation control stage may have to carry, // in the order glslang declares them - which is the order a redeclaration must use. - // Which of them exist is a function of the neighbouring stage's GLSL VERSION + // Which of them exist is a function of the neighboring stage's GLSL VERSION // (gl_CullDistance joins the block at #version 450), so the mask is read off that // stage's SPIR-V rather than assumed. See ReflectPerVertexInputMembers. enum class PerVertexMemberBit : Uint32 { @@ -647,7 +647,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // member set, because all three decide what the generator emits. The size comes from // PATCH_VERTICES and the levels from PATCH_DEFAULT_OUTER_LEVEL / PATCH_DEFAULT_INNER_LEVEL // - draw state rather than link state, and the CTS case that motivated this links at the - // default 3 and draws at 4. The member set comes from the neighbouring evaluation stage's + // default 3 and draws at 4. The member set comes from the neighboring evaluation stage's // own SPIR-V, so two programs at different GLSL versions need different modules. The // pipeline cache re-keys on the same inputs, so the module a pipeline was built with is // part of that pipeline's identity. Compiling is bounded by the number of distinct diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainObject.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainObject.h index 58160c02..a5d8804c 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainObject.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/SwapchainObject.h @@ -66,9 +66,9 @@ namespace MobileGL::MG_Backend::DirectVulkan { // EGL content-validity tracking for the default framebuffer. A color // buffer's content is undefined once its image has been presented - // (EGL_BUFFER_DESTROYED swap behaviour, the implementation default), + // (EGL_BUFFER_DESTROYED swap behavior, the implementation default), // and every ancillary (depth/stencil) buffer's content is undefined - // after ANY swap regardless of swap behaviour (EGL 1.5 §3.10.1). The + // after ANY swap regardless of swap behavior (EGL 1.5 §3.10.1). The // render-pass manager turns an undefined attachment's tile load into // LOAD_OP_DONT_CARE. Flags start false (a fresh swapchain image holds // garbage) and a render pass storing into an attachment sets it back diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.cpp index d8e29c40..16ef2f13 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.cpp @@ -430,7 +430,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // submission still carries, and run_trace_case.cmake reds a split retrace on any // "MGWIRE-FLOOR unsound-serial-complete" line, which is that fix's lane. // - // THE SUBMISSION TERM IS A PROBE AND A DEFENCE, NOT A SECOND GUARANTEE. It is not sound + // THE SUBMISSION TERM IS A PROBE AND A DEFENSE, NOT A SECOND GUARANTEE. It is not sound // on its own: lastUseSubmitIndex is stamped at AcquireWireSlice with the next submission // index, but the draw that acquired the slice can still be pushed into a LATER // submission - BindProgramUniformBuffers -> SyncWireTextureShape's preserve path -> @@ -458,7 +458,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } else if (busyBySerial || busyBySubmission) { // Vulkan buffer copies require four-byte aligned ranges. An odd GL // byte update waits, then writes only the exact range; rounding it - // from a CPU shadow could overwrite neighbouring GPU-written bytes. + // from a CPU shadow could overwrite neighboring GPU-written bytes. if (((offset | size) & 3u) == 0) { uploaded = StagedWireRangeCopy(*resource, bytes, static_cast(offset), static_cast(size)); } @@ -589,7 +589,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } // B3: the draw this slice is being acquired for is normally recorded into the NEXT // submission - normally, not always: a mid-draw flush (SyncWireTextureShape's preserve - // path) can submit this index without the draw. This stamp is the defence term's input + // path) can submit this index without the draw. This stamp is the defense term's input // (see WriteWireBuffer); the floor behind lastUseSerial is the guarantee. Read off the // owning renderer's counter (its GetWireNextSubmitIndex()) when it was handed one. if (m_submitCounter != nullptr) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.h index 387053de..1c7c0d85 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkBufferManager.h @@ -192,7 +192,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { Uint64 size = 0; Uint64 lastUseSerial = 0; // P7 wave 2 package B3: the submission expected to carry the most recent GPU use - // of this buffer - the busy predicate's DEFENCE term, not its guarantee (see + // of this buffer - the busy predicate's DEFENSE term, not its guarantee (see // WriteWireBuffer). IsSubmitIndexComplete polls the real fence and reports an // unsubmitted index as incomplete, but the stamp is taken before the draw is // recorded and a mid-draw flush can submit it without the draw. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp index 368c36ba..2fc4d5ca 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.cpp @@ -57,7 +57,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (MG_Pipe::gPipeInputs->IsCapabilityEnabled(MobileGL::CapabilityInput::FramebufferSrgb)) return; if (ResolveSrgbAttachmentWriteFormat(destinationFormat, false) == destinationFormat) return; - // sRGB -> linear (GL 4.6 core 8.24), applied to the colour channels only: alpha is stored + // sRGB -> linear (GL 4.6 core 8.24), applied to the color channels only: alpha is stored // linearly in an sRGB format and must pass through untouched. const auto toLinear = [](Float encoded) { const Float value = std::clamp(encoded, 0.0f, 1.0f); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h index a0375a88..f6b28d0a 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkClearManager.h @@ -24,7 +24,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { Uint32 stencil{}; }; - // A colour clear reaches us from one of glClear/ClearBufferfv, ClearBufferiv or + // A color clear reaches us from one of glClear/ClearBufferfv, ClearBufferiv or // ClearBufferuiv, and Vulkan reads VkClearColorValue's union according to the destination // image's format rather than converting between the members - a float written where an // integer format is expected is reinterpreted bit for bit, not rounded. Remember which entry @@ -53,7 +53,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // vkCmdClearColorImage names the image, so the driver applies the destination format's transfer // function to whatever value it is handed. Every other write path in this backend goes through // the UNORM twin view while GL_FRAMEBUFFER_SRGB is off (ResolveSrgbAttachmentWriteFormat) and - // therefore stores the raw value GL asked for. Rewrites `payload` to the linear colour whose + // therefore stores the raw value GL asked for. Rewrites `payload` to the linear color whose // encoding is that raw value, so a direct image clear of an sRGB destination agrees with them. // A no-op for every other format, for integer clear encodings, and when GL is doing the // encoding itself. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp index 56ee8807..f5a42234 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.cpp @@ -28,7 +28,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // ResolveAttachmentLayerCount lives in VkTextureManager.h, beside ToVulkanLevelExtent, because // VkClearManager needs the SAME answer: its pending-clear key's layerCount becomes a real - // VkImageSubresourceRange when a clear is materialised outside a render pass. See the header. + // VkImageSubresourceRange when a clear is materialized outside a render pass. See the header. DepthStencilAttachmentLoadInfo ResolveDepthStencilAttachmentLoadInfo(VkImageLayout trackedLayout, Bool clearDepth, Bool clearStencil) { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.h index c8b24160..a5046cff 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkRenderPassManager.h @@ -81,7 +81,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // which std::swap(pair&, pair&) requires. That was invisible while UnorderedMap // only ever move-CONSTRUCTED an element into a fresh slot. ska::flat_hash_map // probes robin-hood: inserting swaps the entry being placed against the one - // already sitting in the slot whenever it has travelled further from its desired + // already sitting in the slot whenever it has traveled further from its desired // position, so the mapped type has to be swappable or the table fails to // instantiate at all. // diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.cpp index c3aa78b0..7ba87ce5 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.cpp @@ -139,7 +139,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Unsigned packed floats: no sign bit at all. 65024 is the largest 11-bit float; the // 10-bit blue channel tops out lower (64512) and RGB9E5 higher (65408), but the bound // that matters for correctness is the lower one, and a single conservative upper bound - // costs nothing a real border colour will ever notice. + // costs nothing a real border color will ever notice. case TextureInternalFormat::R11FG11FB10F: return {true, 0.0f, 64512.0f}; case TextureInternalFormat::RGB9E5: @@ -152,7 +152,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Per-component representable range of an integer texture format, as Int64 so that the whole // signed and unsigned 32-bit ranges are expressible in one type and the clamp can be written // once for both domains. Alpha is carried separately because RGB10_A2UI is the one format - // whose alpha is narrower than its colour channels. + // whose alpha is narrower than its color channels. struct IntegerBorderRange { Int64 rgbMin = 0; Int64 rgbMax = 0; @@ -360,7 +360,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const auto compareFunc = sampler.GetSamplerCompareFunc(); XXHASH_VERIFY(XXH64_update(hashState, &compareFunc, sizeof(compareFunc))); // The resolved enum AND, when it is one of the *_CUSTOM_EXT values, the sixteen bytes of the - // colour itself: two samplers that differ only in a custom border colour carry the same enum + // color itself: two samplers that differ only in a custom border color carry the same enum // and would otherwise collide onto whichever one was created first. XXHASH_VERIFY(XXH64_update(hashState, &borderColor.color, sizeof(borderColor.color))); if (borderColor.isCustom) { @@ -512,14 +512,14 @@ namespace MobileGL::MG_Backend::DirectVulkan { return resolved; // FLOAT_TRANSPARENT_BLACK, never sampled } - // Border colour is sampler state: a bound sampler object supplies its own, and a texture + // Border color is sampler state: a bound sampler object supplies its own, and a texture // with none reaches the very same value through the sampler object it owns. const auto domain = ResolveBorderColorDomain(format); const Bool canUseCustom = m_customBorderColorSupported && m_maxCustomBorderColorSamplers > 0 && m_customBorderColorSamplerCount < m_maxCustomBorderColorSamplers; if (domain != BorderColorDomain::Float) { - // An integer image view REQUIRES an integer border colour, whatever the value is - even + // An integer image view REQUIRES an integer border color, whatever the value is - even // (0,0,0,1). The value itself is whichever integer form the application wrote; a float // border on an integer texture is nonsense GL leaves undefined, so the derived integer // representation (a plain cast) is as good an answer as any. @@ -528,7 +528,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // through Int64 so the whole signed and unsigned 32-bit ranges are expressible at once. // // Which representation to start from is the TEXTURE's domain, not the entry-point form - // the application used. GL 4.6 core 8.10 stores an "I"-form border colour unmodified with + // the application used. GL 4.6 core 8.10 stores an "I"-form border color unmodified with // an integer internal data type and does not define a sign conversion between the two // integer forms, so the stored bits are reinterpreted in the sampled format's own // signedness. Measured, not assumed: a border of -1 written with glTexParameterIiv @@ -578,7 +578,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } return resolved; } - // No custom colour available: pick the nearest of the three integer palette entries + // No custom color available: pick the nearest of the three integer palette entries // rather than always answering transparent black, which is what turned an integer border // of (-1,-1,-1,-1) into 0 and broke the CTS's clamped-texel detection outright. const Bool opaque = clamped[3] != 0; @@ -588,7 +588,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return resolved; } - // Float domain. GL 4.6 core 8.14.2/8.23: the border colour is interpreted in the texture's + // Float domain. GL 4.6 core 8.14.2/8.23: the border color is interpreted in the texture's // format, so it is clamped to that format's representable range first. Without the clamp the // CTS's border of (255,255,255,255) on a GL_RGBA8 texture matched none of the palette entries // and fell through to transparent black - every border texel sampled 0 where the test wanted diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.h index bcc4cd91..5e043ec5 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkSamplerManager.h @@ -32,7 +32,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // customBorderColorWithoutFormat; see VulkanRenderer::m_customBorderColorFeatureEnabled. Bool customBorderColorSupported = false; // VkPhysicalDeviceCustomBorderColorPropertiesEXT::maxCustomBorderColorSamplers. A hard device - // limit on how many LIVE samplers may carry a custom border colour, so the cache counts them + // limit on how many LIVE samplers may carry a custom border color, so the cache counts them // and falls back to the snapped predefined value once it is reached. Uint32 maxCustomBorderColorSamplers = 0; }; @@ -70,7 +70,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Resolved ONCE per GetOrCreateSampler call and threaded into both the cache key and the // create-info, so the two cannot disagree - the same discipline the resolved anisotropy needs, // and here it also makes the maxCustomBorderColorSamplers fallback deterministic: whether a - // custom colour was affordable is decided before the key is built, not twice with a budget + // custom color was affordable is decided before the key is built, not twice with a budget // change in between. struct ResolvedBorderColor { VkBorderColor color = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK; @@ -115,7 +115,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { Float m_maxSamplerAnisotropy = 1.0f; Bool m_customBorderColorSupported = false; Uint32 m_maxCustomBorderColorSamplers = 0; - // Live cache entries carrying a custom border colour. Kept in step with the entries themselves + // Live cache entries carrying a custom border color. Kept in step with the entries themselves // in exactly the three places one can appear or disappear: creation, the OnFrameBoundary sweep, // and Shutdown. Uint32 m_customBorderColorSamplerCount = 0; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp index e46f2b2b..c24d349f 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp @@ -732,7 +732,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // TryResolveTextureShapeInfo's answers derived from the wire descriptor instead of the // frontend object. The descriptor's Width/Height/Depth are the BASE level's GL extent and - // ArrayLayers the layer count the emitter already normalised (MGPipeTextureExtentOf: a 1D + // ArrayLayers the layer count the emitter already normalized (MGPipeTextureExtentOf: a 1D // array's layers are already out of its height, a cube map reports 6). static Bool ResolveWireTextureShapeInfo(const MG_Pipe::MGPResourceDesc& desc, TextureShapeInfo& outShape) { using MG_Pipe::MGPipeResourceTarget; @@ -768,7 +768,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { outShape.arrayLayers = 6; return desc.Width > 0 && desc.Width == desc.Height; case MGPipeResourceTarget::TexCubeArray: - // glTexStorage3D hands 6n through as the depth; the emitter normalised it into + // glTexStorage3D hands 6n through as the depth; the emitter normalized it into // ArrayLayers. A non-whole cube count has no Vulkan shape - declined like every // other unrepresentable target. outShape.viewType = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY; @@ -1706,7 +1706,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } // The RGBA8/RGBX8 buffers the registry allocates have a Vulkan format; an external-only - // format would need a YCbCr conversion and is not a colour buffer this path can write. + // format would need a YCbCr conversion and is not a color buffer this path can write. if (formatProperties.format == VK_FORMAT_UNDEFINED) { why = "the buffer has no Vulkan format (external format only)"; return false; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.h index 4f546a09..e10a6d00 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.h @@ -84,9 +84,9 @@ namespace MobileGL::MG_Backend::DirectVulkan { // again in VkClearManager.cpp - and the two are not independent: the render pass builds the // attachment view and VkFramebufferCreateInfo::layers from one, while the CLEAR key built from the // other is written verbatim into VkImageSubresourceRange::layerCount when a queued glClear is - // materialised outside a render pass (MaterializePendingClearForTexture). They are two consumers + // materialized outside a render pass (MaterializePendingClearForTexture). They are two consumers // of the same GL clear, so any disagreement means the same glClear produces two different pictures - // depending only on which path happens to consume it first - and the materialise path then POPS + // depending only on which path happens to consume it first - and the materialize path then POPS // the entry, so the other one never runs. Fixing one copy and leaving the other is exactly how // that split gets introduced; keep them the same function. // @@ -586,7 +586,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { Uint32 layerCount = 1); // SHARED IMAGES: a server shared image's - // AHardwareBuffer bound as a single-level 2D colour image on THIS session's device, on dedicated + // AHardwareBuffer bound as a single-level 2D color image on THIS session's device, on dedicated // memory imported from the buffer. Android only (false with `why` elsewhere, or when the device // did not take the AHardwareBuffer extension). The image is born UNDEFINED; whoever uses it // acquires it from the foreign queue family first, and a writer releases it back after. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h index d5ca5bd5..09cb7525 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.h @@ -296,7 +296,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // `defaultFramebufferOrientation` is set only when the source is the swapchain's // depth/stencil image, which this renderer stores display-side-up: the copy rect then // has to be mapped out of GL's bottom-origin space and the copied rows re-oriented on - // the way back, exactly as the colour ReadPixels path does. + // the way back, exactly as the color ReadPixels path does. // `sourceLayerCount` above 1 says the `height` rows the client is owed are stored as that // many ARRAY LAYERS of a one-row image rather than as rows of one layer - the shape a GL // 1D array has in Vulkan. The two produce byte-identical tightly-packed readbacks, so @@ -651,7 +651,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // and the default draw framebuffer alike. The CAPABILITY decline inside // ResolveWireDepthStencil (a stencil-only resolve without VK_EXT_shader_stencil_export // on a device without VK_KHR_depth_stencil_resolve) is still decided per aspect, after - // colour ran; rule I (a) accepts that (§2.10). + // color ran; rule I (a) accepts that (§2.10). Bool DeclineWireDepthStencilResolveShape(const WireImage& source, const WireImage& destination, GLint sx0, GLint sy0, GLint sx1, GLint sy1, GLint dx0, GLint dy0, GLint dx1, GLint dy1); @@ -682,7 +682,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { Bool m_wireAhbImport = false; void* m_wireGetAhbProperties = nullptr; // YUV shared images (WireYuvImage.cpp): the device enabled samplerYcbcrConversion, and the - // conversion pipelines made so far (one per buffer format and colour conversion). + // conversion pipelines made so far (one per buffer format and color conversion). Bool m_samplerYcbcrConversion = false; struct WireYuvResources; WireYuvResources* m_wireYuvResources = nullptr; @@ -704,7 +704,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { UnorderedMap m_sharedImagePresentTargets; void DestroySharedImagePresentTargets(Bool onlyDead); - // SHARED-IMAGE SYNCHRONISATION (WireSharedImage.cpp). The sync_file fences other sessions + // SHARED-IMAGE SYNCHRONIZATION (WireSharedImage.cpp). The sync_file fences other sessions // publish become binary semaphores: a temporary SYNC_FD import is a WAIT, an exportable // semaphore a SIGNAL, of the next frame submission - whichever of SubmitPendingCommandBuffer // and Present's submit comes first, which is the one carrying what was recorded since. @@ -1185,9 +1185,9 @@ namespace MobileGL::MG_Backend::DirectVulkan { // VK_EXT_custom_border_color. Vulkan's four predefined VkBorderColor values cover only // transparent/opaque black and opaque white; GL_TEXTURE_BORDER_COLOR is an arbitrary vec4 (or // an arbitrary ivec4/uvec4 through the "I" entry points). Without this extension a border - // colour outside the palette has to be snapped to the nearest predefined one. Both features + // color outside the palette has to be snapped to the nearest predefined one. Both features // are required together: customBorderColorWithoutFormat is what lets a sampler carry a custom - // colour without naming the image format it will be paired with, which GL's sampler objects + // color without naming the image format it will be paired with, which GL's sampler objects // cannot know. maxCustomBorderColorSamplers is a real device limit, so the sampler cache has // to be able to fall back to the snapped value once it is reached. Bool m_customBorderColorFeatureEnabled = false; @@ -1249,7 +1249,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // pipeline from asking for LAST on a device that cannot preserve a fan's provoking vertex. Bool m_provokingVertexXfbPreserveEnabled = false; // provokingVertexModePerPipeline: when VK_FALSE every pipeline in one render pass instance - // must agree on the mode, so glProvokingVertex(GL_FIRST_VERTEX_CONVENTION) cannot be honoured + // must agree on the mode, so glProvokingVertex(GL_FIRST_VERTEX_CONVENTION) cannot be honored // per draw and every pipeline takes GL's default (LAST) instead. Bool m_provokingVertexModePerPipeline = false; // transformFeedbackPreservesTriangleFanProvokingVertex. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererCopy.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererCopy.cpp index 31c58df2..86669a35 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererCopy.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererCopy.cpp @@ -726,11 +726,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Nothing else on this path asks: the three checks around it cover the mip range, the region // bounds and the slice range, and none of them ever looked at a format. // - // A decline rather than a MOBILEGL_ASSERT, for the reason the neighbouring guards spell out: + // A decline rather than a MOBILEGL_ASSERT, for the reason the neighboring guards spell out: // assertions compile out of the release build that the CTS and shipping both run, which is // exactly where the corruption was observed. if (srcImage.format != dstImage.format) { - // Size-compatibility is the COLOUR rule. Vulkan makes each depth/stencil format compatible + // Size-compatibility is the COLOR rule. Vulkan makes each depth/stencil format compatible // only with ITSELF, and the texel block sizes cannot tell them apart: X8_D24_UNORM_PACK32, // D32_SFLOAT and D24_UNORM_S8_UINT are all 4 bytes and all in different compatibility // classes, so a raw block-size test waves through exactly the pairs Vulkan forbids. The @@ -1419,9 +1419,9 @@ namespace MobileGL::MG_Backend::DirectVulkan { VK_PIPELINE_STAGE_TRANSFER_BIT, srcAccessMask, VK_ACCESS_TRANSFER_READ_BIT, imageAspect, mipLevel, 1); MOBILEGL_ASSERT(ok, "%s: failed to transition depth-stencil source image", __func__); - // The swapchain's depth/stencil image is stored display-side-up like its colour twin, so + // The swapchain's depth/stencil image is stored display-side-up like its color twin, so // the GL rect has to be mapped into that space before the copy and the copied rows - // re-oriented afterwards - the same two halves the colour ReadPixels path applies. + // re-oriented afterwards - the same two halves the color ReadPixels path applies. VkOffset2D copyOffset{x, y}; VkExtent2D copyExtent{static_cast(width), static_cast(height)}; if (defaultFramebufferOrientation) { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererDevice.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererDevice.cpp index 5efd01be..adaccdd9 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererDevice.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererDevice.cpp @@ -755,7 +755,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // P11 B2 (T0): a client's AHardwareBuffer imported as a wire buffer store. Wire arms, on // Android, whenever the device advertises the extension - not per session: the device is // created once per server and a later session asking T0 must find it able. Enabling it - // changes no T2 behaviour; only an import uses it. The 1.0-era dependencies are core at the + // changes no T2 behavior; only an import uses it. The 1.0-era dependencies are core at the // 1.1 this device is created at, and are enabled too when advertised (the spike's set). m_wireAhbImport = false; m_wireGetAhbProperties = nullptr; @@ -943,7 +943,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // an integer border of -1 come back as 0. // // customBorderColorWithoutFormat is required alongside customBorderColors, not merely - // preferred: a GL sampler object carries a border colour with no idea which texture it will + // preferred: a GL sampler object carries a border color with no idea which texture it will // be paired with, so the VkSamplerCustomBorderColorCreateInfoEXT this backend builds has to // leave `format` VK_FORMAT_UNDEFINED. m_customBorderColorFeatureEnabled = false; @@ -987,7 +987,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Native subgroup topology, and VK_EXT_subgroup_size_control's // computeFullSubgroups feature. REQUIRE_FULL_SUBGROUPS on a compute stage is what // turns the derived gl_NumSubgroups (DeriveNumSubgroupsPass) from - // encouraged-but-unspecified driver behaviour into a spec guarantee: with the bit + // encouraged-but-unspecified driver behavior into a spec guarantee: with the bit // set and local_size_x a multiple of the subgroup size, every subgroup launches // full, so the subgroup count is exactly invocations / size ("Full Subgroups", // VUID-VkPipelineShaderStageCreateInfo-flags-02759/-02785). diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererDraw.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererDraw.cpp index 6439958d..af17748b 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererDraw.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererDraw.cpp @@ -90,11 +90,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { // end up with a module carrying no Xfb mode - the clip/XFB validation backstop rewinding // past the decoration, or XfbCaptureDecoratePass resolving none of the requested varyings // and changing nothing. Declining the span leaves the capture buffers untouched, which is - // the same nothing the driver would have written, without the undefined behaviour. + // the same nothing the driver would have written, without the undefined behavior. if (m_currentDrawXfbCaptureDeclined) { MGLOG_E_ONCE("BeginXfbCaptureForDraw: declining the capture span - the bound program's last " "pre-rasterization stage carries no Xfb execution mode, so recording one would be " - "undefined behaviour rather than a capture"); + "undefined behavior rather than a capture"); return false; } return BeginWireXfbCaptureForDraw(frame); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererPipeline.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererPipeline.cpp index f6dd8454..c523e7df 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererPipeline.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererPipeline.cpp @@ -74,7 +74,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // // Rectangles were never converted. The viewport, the scissor and the ReadPixels copy offset // all used the GL bottom-origin Y verbatim as a Vulkan top-origin Y, which is correct only - // when y == H - y - h (full height, or vertically centred) - and full height is the only case + // when y == H - y - h (full height, or vertically centered) - and full height is the only case // any test ever exercised. In the conformance suite the errors CANCEL in placement (the draw // lands in Vulkan rows [y, y+h) and the readback copies the same rows back) and compose into // an exact vertical flip: 1,759 of Magma's 1,793 non-passing cases, 861 vertical flips and @@ -155,7 +155,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // The GL viewport rect, expressed against the default framebuffer's stored orientation. // A full-height viewport is unchanged by this, which is why every existing scenario keeps - // its exact behaviour. + // its exact behavior. if (isDefaultFramebuffer) { const DefaultFramebufferRectMapping mapping = GetDefaultFramebufferRectMapping(preTransform); viewportX = MapDefaultFramebufferRectAxis(viewportX, viewportWidth, framebufferExtent.x(), mapping.mirrorX); @@ -338,7 +338,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { static_cast(std::max(0, rawY1 - rawY0)), }; // A quarter turn maps to {false, false}, so this is a no-op today; it is here so the - // branch cannot drift away from the identity/180 one when quarter turns are modelled. + // branch cannot drift away from the identity/180 one when quarter turns are modeled. return MapScissorRectToDefaultFramebuffer(scissor, framebufferExtent, preTransform); } @@ -670,8 +670,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { // - patch vertices, polygon mode, cull face mode, depth func, logic op, // min sample shading, the glSampleMaski word // - front/back stencil ops + compare funcs (ref/mask are dynamic state) - // - per draw buffer up to the render pass's colour span: indexed blend enable, - // blend factors/equations, indexed colour write mask (broadcast from index 0 + // - per draw buffer up to the render pass's color span: indexed blend enable, + // blend factors/equations, indexed color write mask (broadcast from index 0 // when the device lacks independentBlend - the same read the payload does) // FBO-derived payload inputs (attachment presence/formats/draw-buffer gating) are // pinned by the render-pass hash key, exactly as the version-keyed memo relied on. @@ -1078,7 +1078,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // is an OVER-count, which breaks the lower-bound contract every other tally keeps. // // The 15 are: the six capability reads (cull face, depth test, polygon offset - // fill, rasterizer discard, colour logic op, stencil test), the draw-FBO slot + // fill, rasterizer discard, color logic op, stencil test), the draw-FBO slot // read that gates depth/stencil, the two stencil face states, the polygon mode, // the min sample shading value, the patch vertex count, the depth mask, the depth // func, and the second draw-FBO slot read below. The sample-shading CAPABILITY @@ -1103,7 +1103,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { .sampleShadingEnable = m_sampleRateShadingFeatureEnabled && MG_Pipe::gPipeInputs->IsCapabilityEnabled(CapabilityInput::SampleShading), .minSampleShading = MG_Pipe::gPipeInputs->GetMinSampleShadingValue(), - // Word 1 keeps its all-ones initialiser: GL has no state for samples 32..63. + // Word 1 keeps its all-ones initializer: GL has no state for samples 32..63. .sampleMask = {ResolveEffectiveSampleMask(renderPassEntry.sampleCount), 0xffffffffu}, .subpass = 0, .topology = vkTopology, @@ -1121,7 +1121,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // over the same rows), and a Y-negated position - the default framebuffer's flip or // an upper-left clip origin - reverses the winding once more. Expressed as the front // face rather than as swapped cull bits so gl_FrontFacing agrees with culling, and - // so glFrontFace(GL_CW) is honoured. + // so glFrontFace(GL_CW) is honored. .frontFace = ((MG_Pipe::gPipeInputs->GetRenderStateParameters().FrontFaceModeSetting == FrontFaceMode::Clockwise) != invertClockwise) ? VK_FRONT_FACE_COUNTER_CLOCKWISE @@ -1164,7 +1164,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // attached and CreatePipeline refuses the pipeline, which skips the draw. // // Gated on the PATCH topology as well, and that gate is load-bearing rather than an - // optimisation: patchControlPoints is only meaningful for a patch draw, and a pipeline + // optimization: patchControlPoints is only meaningful for a patch draw, and a pipeline // that carries tessellation stages while its topology is anything else violates // VUID-VkGraphicsPipelineCreateInfo-topology-00737 - the same class of invalid input as // the missing control stage, on the same driver. Such a draw is illegal in GL too (a @@ -1217,7 +1217,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { payload.backStencilCompareOp = VK_COMPARE_OP_ALWAYS; } const Uint32 fragmentOutputMask = programObj.activeFragmentOutputLocationMask; - // Outputs at locations past the render pass's trimmed colour span are + // Outputs at locations past the render pass's trimmed color span are // simply discarded - GL's semantic for a fragment output whose draw // buffer is GL_NONE (the trailing UNUSED slots no longer occupy // references, see GetOrCreateRenderPass). @@ -1340,7 +1340,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // VUID-VkPipelineColorBlendAttachmentState-srcColorBlendFactor-00608 and its three // siblings forbid a VK_BLEND_FACTOR_SRC1_* in the struct without the feature whatever // blendEnable says, so clearing only the enable would still be invalid pipeline state. - // The previous behaviour, throwing, took the whole process down over one unsupported + // The previous behavior, throwing, took the whole process down over one unsupported // blend factor; this is defined, survivable and visible in the log, and it matches what // the non-blendable-format arm above already does. if (!m_dualSrcBlendFeatureEnabled && diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererPresent.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererPresent.cpp index d0e50727..a6090a22 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererPresent.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererPresent.cpp @@ -190,7 +190,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VK_VERIFY(result, "Present, vkQueuePresentKHR"); // EGL swap semantics: the presented color buffer's content is undefined the // next time this image is acquired (EGL_BUFFER_DESTROYED, the default swap - // behaviour), and EVERY ancillary depth/stencil buffer's content is + // behavior), and EVERY ancillary depth/stencil buffer's content is // undefined after any swap. The render-pass manager turns the undefined // attachments' next tile loads into LOAD_OP_DONT_CARE. // diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererSubmit.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererSubmit.cpp index fc8da358..903d1d39 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererSubmit.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRendererSubmit.cpp @@ -212,7 +212,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // The floor now advances only to a serial NO remaining in-flight submission still // carries. NotifyFrameSerialComplete is monotone and already refuses the still- // recording serial, so this can only ever advance the floor later, never further. - // On the disaggregated build's MONOLITH arm this is behaviour-identical (one + // On the disaggregated build's MONOLITH arm this is behavior-identical (one // submission per serial). The #else branch below is the pull build's statement, // unchanged, which is what keeps G1's .text byte-identical. Bool retiredAny = false; @@ -707,7 +707,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } // Only provokingVertexModePerPipeline lets modes differ inside one render pass instance; // elsewhere every pipeline takes GL's default so the render pass stays self-consistent, and - // glProvokingVertex(GL_FIRST_VERTEX_CONVENTION) goes unhonoured. Honouring it there would + // glProvokingVertex(GL_FIRST_VERTEX_CONVENTION) goes unhonoured. Honoring it there would // mean ending the render pass on every glProvokingVertex change; not worth it until a target // device actually lacks the property. if (!m_provokingVertexModePerPipeline) { diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlit.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlit.cpp index 6e0d7173..ec2f64f7 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlit.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlit.cpp @@ -139,7 +139,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // P7 wave 2-B (CONTRACT-P7 §3.2, `default-color-blit-shape`). The shader blit below can only // SAMPLE its source: sampler2D, a float result, and one of two 2D view types. A framebuffer - // whose colour attachment is RGBA8UI, or a layer of a 3D texture, is none of those, and on a + // whose color attachment is RGBA8UI, or a layer of a 3D texture, is none of those, and on a // rotated Android surface there is no other arm - an axis-aligned vkCmdBlitImage cannot // express a quarter turn. So the source region becomes an owned 2D image first, through // vkCmdCopyImage, which cares about the texel BLOCK SIZE and not about how the block is @@ -163,7 +163,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { static_cast(std::max(sx0, sx1)) > source.extent.width || static_cast(std::max(sy0, sy1)) > source.extent.height) return false; - // A compressed source cannot be a colour attachment, so it cannot be a framebuffer blit's + // A compressed source cannot be a color attachment, so it cannot be a framebuffer blit's // source either - but the block arithmetic below would silently produce nonsense for one, // and "cannot happen" is the reason the guards this package retires were written as // asserts. The size-compatibility classes are Vulkan's own (VkFormat texel block size); diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlitFilter.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlitFilter.h index 99d5b194..1b151e05 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlitFilter.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireColorBlitFilter.h @@ -10,28 +10,28 @@ #include #include "../VkIncludes.h" -// P7 g3-blit (g3det, gate 3): WHICH SAMPLER THE WIRE ARM'S SHADER COLOUR BLIT READS ITS SOURCE +// P7 g3-blit (g3det, gate 3): WHICH SAMPLER THE WIRE ARM'S SHADER COLOR BLIT READS ITS SOURCE // THROUGH. // // GL applies a blit's `filter` only where the image is STRETCHED (GL 4.6 core 18.3.1). A blit whose // source and destination rectangles are the same size is a copy, whatever `filter` says, and so is // a mirrored one. The wire arm's shader blit (WireColorBlit.cpp, BlitWireColorImage) draws a quad // and samples `textureLod(sourceImage, texCoord, 0)` at interpolated coordinates, and it used the -// LINEAR sampler for every GL_LINEAR blit. At 1:1 every fragment centre maps to a texel centre, so +// LINEAR sampler for every GL_LINEAR blit. At 1:1 every fragment center maps to a texel center, so // in exact arithmetic linear filtering reads the same single texel. Adreno 830 quantises the -// coordinate to sub-texel precision: a fragment that lands a fraction off the centre blends in a -// small weight of a neighbour. minecraft-1.21.1-neoforge-create-instancing-in-world ends with a +// coordinate to sub-texel precision: a fragment that lands a fraction off the center blends in a +// small weight of a neighbor. minecraft-1.21.1-neoforge-create-instancing-in-world ends with a // 1:1 GL_LINEAR glBlitFramebuffer into FB 0, and on the wire arm 712 high-contrast pixels moved by -// 1 LSB toward a neighbour. The monolith's vkCmdBlitImage copied them exactly -// (~/w7/logs/g3det/VERDICT.md section 3). NEAREST within half a texel of the centre is exact, so an -// unscaled blit takes NEAREST. Lavapipe samples texel centres exactly, so no host picture can see +// 1 LSB toward a neighbor. The monolith's vkCmdBlitImage copied them exactly +// (~/w7/logs/g3det/VERDICT.md section 3). NEAREST within half a texel of the center is exact, so an +// unscaled blit takes NEAREST. Lavapipe samples texel centers exactly, so no host picture can see // the difference; this pure half is what the unit test pins // (MG_Test/Pipeline/PipelineQuirkTest.cpp, WireColorBlitSamples*). // // THE SURFACE TRANSFORM DOES NOT TURN A COPY INTO A STRETCH. BlitWireColorImage applies the // quarter and half turns in NDC, over a viewport of the native image, and for a quarter turn it // takes the logical extent as the native extent swapped. A native pixel then has exactly the pitch -// of a logical one, and the rotation maps pixel centres onto pixel centres. So the scale test is on +// of a logical one, and the rotation maps pixel centers onto pixel centers. So the scale test is on // GL's own (logical) rectangles for identity and all three rotations. BlitWireColorImage declines // any other transform before it chooses a sampler; for one, this answers with the filter's own // mapping, as before this package. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireCopySliceProbe.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireCopySliceProbe.cpp index ba1546a3..76707c6d 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireCopySliceProbe.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireCopySliceProbe.cpp @@ -129,7 +129,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkPhysicalDeviceMemoryProperties memoryProperties{}; vkGetPhysicalDeviceMemoryProperties(context.physicalDevice, &memoryProperties); - // The wire's images (VkTextureManager): MUTABLE_FORMAT (a storage-compatible colour class), + // The wire's images (VkTextureManager): MUTABLE_FORMAT (a storage-compatible color class), // SAMPLED | TRANSFER_SRC | TRANSFER_DST | COLOR_ATTACHMENT, a 3D one 2D_ARRAY_COMPATIBLE. const auto makeImage = [&](Bool volume, VkFormat format, VkImage& out) -> Bool { VkFormatProperties formatProperties{}; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDepthMipmap.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDepthMipmap.cpp index 02d548fc..9d1c857a 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDepthMipmap.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDepthMipmap.cpp @@ -218,7 +218,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { depthStencil.depthCompareOp = VK_COMPARE_OP_ALWAYS; depthStencil.minDepthBounds = 0.0f; depthStencil.maxDepthBounds = 1.0f; - // No colour attachment in this render pass, so no attachment states either. + // No color attachment in this render pass, so no attachment states either. VkPipelineColorBlendStateCreateInfo blend{VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO}; const VkDynamicState dynamicStates[]{VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; VkPipelineDynamicStateCreateInfo dynamic{VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO}; @@ -269,7 +269,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { framebufferInfo.layers = 1; VkFramebuffer framebuffer = VK_NULL_HANDLE; VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferInfo, nullptr, &framebuffer)); - // Each in-flight pass owns its descriptor set, for the colour blit's reason: updating + // Each in-flight pass owns its descriptor set, for the color blit's reason: updating // a cached set would rewrite the source view of an older queued pass. VkDescriptorPool descriptorPool = VK_NULL_HANDLE; VkDescriptorSet descriptorSet = VK_NULL_HANDLE; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDepthResolveProbe.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDepthResolveProbe.cpp index c0cf1b8a..924ef065 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDepthResolveProbe.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDepthResolveProbe.cpp @@ -95,7 +95,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (result != VK_SUCCESS) return result; // THE STENCIL MODULE IS ONLY CREATED WHERE IT CAN RUN: its SPIR-V declares the // StencilExportEXT capability, and handing a module with an unsupported capability to - // vkCreateShaderModule is undefined behaviour - not an error this could catch. + // vkCreateShaderModule is undefined behavior - not an error this could catch. if (shaderStencilExport) { result = shader(kWireMultisampleStencilResolveFragmentSpirv, sizeof(kWireMultisampleStencilResolveFragmentSpirv), kit.stencilFragment); @@ -206,7 +206,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { op.reference = 0; depthStencilState.front = depthStencilState.back = op; } - // No colour attachment in this render pass, so no attachment states either. + // No color attachment in this render pass, so no attachment states either. VkPipelineColorBlendStateCreateInfo blend{VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO}; const VkDynamicState dynamicStates[]{VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR}; VkPipelineDynamicStateCreateInfo dynamic{VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO}; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.cpp index f79dd570..95eaae32 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireDraw.cpp @@ -1175,7 +1175,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Every write goes through the pass's attachment views (the UNORM twin of an sRGB image while // GL_FRAMEBUFFER_SRGB is off, exactly GL's raw clear - no pre-compensation), and wire attachments // live in GENERAL. What none of this expresses goes back to the standalone path, per GL buffer - // bit: a partial colour or stencil write mask (that path warns and skips, as before), an + // bit: a partial color or stencil write mask (that path warns and skips, as before), an // attachment whose extent or layer count differs from the pass's (the pass covers the common area // only), and a stencil clear the pass's depth attachment does not carry. GLbitfield VulkanRenderer::ClearWireFramebufferInPass(const MG_Pipe::MGPFramebufferState& fbo, @@ -1185,7 +1185,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Nested inside a draw's preparation the scratch and the pass belong to that draw. if (m_wirePreparationDepth != 0) return remaining; // NOT THE DEFAULT FRAMEBUFFER (measured, not understood): on Adreno 750 the openra retrace - // loses its palette-sampled sprites (SSIM 0.956) when a colour+depth clear of the default + // loses its palette-sampled sprites (SSIM 0.956) when a color+depth clear of the default // framebuffer becomes part of its draw pass - with LOAD_OP_CLEAR as well as with // vkCmdClearAttachments - while the same clear split across the two paths, or left // standalone, renders correctly. Default-framebuffer clears keep the standalone path until @@ -1354,7 +1354,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } // The draw pass `begun` with LOAD_OP_CLEAR for the attachments `variantKey` names (bit 2a: - // attachment a's colour or depth, bit 2a+1: its stencil). Built once per key and kept on the + // attachment a's color or depth, bit 2a+1: its stencil). Built once per key and kept on the // pass, like the pass itself. VkRenderPass VulkanRenderer::WireClearVariant(RenderPassEntry& begun, Uint64 variantKey) { for (const auto& entry : begun.clearVariants) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireE5RawCopy.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireE5RawCopy.h index eae3ec29..6f398dcc 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireE5RawCopy.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireE5RawCopy.h @@ -25,7 +25,7 @@ // level return every non-canonical word canonicalized, while a 16x16 or 64x64 level reads back verbatim. // The stored words are intact - a shader reading the same image through an R32_UINT view sees // every one of them - and so are transfer WRITES into it. Measured with format lists, without -// the colour-attachment usage and with storage usage: none of them changes the answer, and the +// the color-attachment usage and with storage usage: none of them changes the answer, and the // device has no VK_EXT_image_compression_control to ask with. // // The route therefore reads through a shader: a compute pass fetches the source through an @@ -109,7 +109,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // comparison or the route itself is what failed, and nothing is concluded. Uint32 controlMismatches = 0; // Reported, not judged: the same words in a 16x16 level read back by plain transfer. Clean - // on the device this was characterised on (power-of-two extents read back verbatim, 28, 30 + // on the device this was characterized on (power-of-two extents read back verbatim, 28, 30 // and 31 do not), which is why the subject is 30x30. Uint32 smallTexels = 0; Uint32 smallMismatches = 0; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.cpp index 81ab7da9..388cfea6 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireFramebuffer.cpp @@ -615,7 +615,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } // THE HOST GATE CANNOT REACH THE SHADER MIP ARM ON ITS OWN. lavapipe reports - // BLIT_SRC|BLIT_DST for every colour format this lane can create, so `nativeBlit` is + // BLIT_SRC|BLIT_DST for every color format this lane can create, so `nativeBlit` is // always true there and both shader shapes below would only ever run on the phone - // which is how the Adreno refusal reached a release in the first place. The knob makes // them reachable from a host lane and is read exactly once: @@ -789,7 +789,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // ---- P15: WIRE DEFERRED CLEARS ------------------------------------------------------------- // // Minecraft (1.21.5) clears its targets through framebuffers of their own - a depth-only one - // for the shared depth texture, a colour+depth one per target - and then draws through the + // for the shared depth texture, a color+depth one per target - and then draws through the // main framebuffer. A clear that begins a LOAD_OP_CLEAR pass of its own made every such clear a // pass that did nothing but clear, closed by the very next draw: 11.5 passes a frame against // dev's 4.1 (whose clear manager folded the same clears into the next pass's load op), each @@ -805,7 +805,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // ClearWireFramebufferInPass), and it is presented, not sampled. // Whether `image` can carry a deferred clear: a plain single-sample 2D(-array) image of this - // session with a float colour or a depth/stencil format, clearable by a transfer command. + // session with a float color or a depth/stencil format, clearable by a transfer command. Bool VulkanRenderer::WireImageCanDeferClear(const WireImage& image) { const auto* resource = image.resource; if (resource == nullptr || image.isDefault || image.is3D || image.samples != VK_SAMPLE_COUNT_1_BIT) @@ -1328,7 +1328,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { !m_swapchainObject.IsImageContentDefined(source.swapchainImageIndex)) { // Named rather than silent: the readback hands back whatever the image holds. The // ordinary cause is a readback of the default framebuffer applied after the Present - // that consumed it, where the app's own colour is still what is expected (see + // that consumed it, where the app's own color is still what is expected (see // m_defaultFramebufferImageIndex). MGLOG_W_ONCE("DirectVulkan::ReadPixels: no write is recorded for swapchain image %u of the " "default framebuffer; the readback returns its raw pixels", @@ -1416,7 +1416,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { const Int64 dstHeight = dstSpanY < 0 ? -dstSpanY : dstSpanY; // A SCALE has no arm here and is not supposed to: 18.3.1 makes a multisample blit whose // rectangles differ in size INVALID_OPERATION. Rule I (a), the same three lines the - // colour arm's multisample-destination decline uses. A ZERO span on one side only is a + // color arm's multisample-destination decline uses. A ZERO span on one side only is a // size mismatch too (review round 2): it used to return silently with the other side // non-empty, where GL raises the error. Only when BOTH sides are empty on an axis is // there nothing to do and nothing to say - that is the caller's early return. @@ -1602,7 +1602,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // P7 wave 2-B2 (review round): A REVERSED RECTANGLE IS NOT A MALFORMED ONE. This guard // used to require `sx1 > sx0` and `sy1 > sy0` and take the session with a named Fatal // otherwise - so `glBlitFramebuffer(0, h, w, 0, 0, 0, w, h, COLOR|DEPTH)` out of a - // multisample framebuffer blitted its COLOUR correctly (the colour arm has handled a + // multisample framebuffer blitted its COLOR correctly (the color arm has handled a // flip since P5f and now handles a scale too) and then died on its DEPTH. GL 4.6 core // 18.3.1 asks for identical DIMENSIONS, not identical corners - a conforming check compares absolute // spans - so a flip is a legal blit that has to produce a mirrored picture. @@ -1610,10 +1610,10 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Spans are therefore signed and everything downstream works off the min corner. // // THE SHAPE DECLINES ARE DECIDED ONCE PER CALL (review round 2). BlitWireFramebuffers - // asks DeclineWireDepthStencilResolveShape before ANY aspect runs, because the colour + // asks DeclineWireDepthStencilResolveShape before ANY aspect runs, because the color // lambda runs first: asked only here, a scaled COLOR|DEPTH blit scaled and wrote its - // colour and THEN recorded INVALID_OPERATION on its depth - a partial effect GL 18.3.1 - // forbids (the whole call errors) - and an X-mirrored one mirrored its colour and left + // color and THEN recorded INVALID_OPERATION on its depth - a partial effect GL 18.3.1 + // forbids (the whole call errors) - and an X-mirrored one mirrored its color and left // its depth alone. The call below is the same question for a caller that did not ask; // on the BlitWireFramebuffers path it has already answered false. if (DeclineWireDepthStencilResolveShape(source, destination, sx0, sy0, sx1, sy1, dx0, dy0, dx1, dy1)) return; @@ -1874,8 +1874,8 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (!read || !draw) MagmaWireFatal("blit-framebuffer-record"); state.VerbBlitNamedConsumed = named; // P7 wave 2-B2 (review round 2): ONE ANSWER FOR THE WHOLE CALL. The aspects below run - // colour first, so a multisample depth/stencil shape that declines (a scale, an X - // mirror, a Y mirror across two formats) used to be discovered only after the colour + // color first, so a multisample depth/stencil shape that declines (a scale, an X + // mirror, a Y mirror across two formats) used to be discovered only after the color // attachment had already been scaled or mirrored and written - the call then recorded // INVALID_OPERATION with half its effect in place, which GL 18.3.1 does not allow (an // erroring blit writes nothing). The shape is a fact about the rectangles and the two @@ -1887,7 +1887,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // on the belief that a default draw behind a multisample read was ResolveWireDepthStencil's // region Fatal whatever the shape, but that arm asks DeclineWireDepthStencilResolveShape // BEFORE its region check - so a scaled (or X-mirrored) COLOR|DEPTH blit out of a - // multisample framebuffer onto the window scaled and wrote its colour through + // multisample framebuffer onto the window scaled and wrote its color through // BlitWireColorToDefault and then recorded INVALID_OPERATION on its depth, the very // partial effect this block exists to close. Both sides are resolved as READS // (isWriteTarget=false): only their format and samples are consulted here, and a write @@ -2005,7 +2005,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // The filter only started MATTERING with the scale above: at 1:1 LINEAR and // NEAREST read the same texel, so nothing here ever asked whether the format // could be filtered. VK_FILTER_LINEAR on a source whose optimalTilingFeatures - // lack SAMPLED_IMAGE_FILTER_LINEAR is undefined behaviour, and GL says filter + // lack SAMPLED_IMAGE_FILTER_LINEAR is undefined behavior, and GL says filter // is ignored for a multisample resolve in the first place - so a format that // cannot be filtered takes NEAREST rather than the command being illegal. VkFormatProperties scratchProperties{}; @@ -2077,7 +2077,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // express a quarter turn. It is still TAKEN FIRST on every transform it can // express, identity included. That has been the routing since 38919d453: every // host lane (all identity) and the Redmi pbuffer run their default-framebuffer - // colour blits through it, F1WireScenario.ColorBlitToDefaultHonorsScissorAndReversedRect + // color blits through it, F1WireScenario.ColorBlitToDefaultHonorsScissorAndReversedRect // among them. The ordinary vkCmdBlitImage arm below is reached on identity only // when this pass declines the source. Because identity blits run here, the pass // must copy exactly wherever GL says the blit is a copy: an unscaled blit samples @@ -2179,7 +2179,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // P7 wave 2-B2, CONTRACT-P7 §3.2: WHAT IS LEFT HERE IS A MULTISAMPLE DESTINATION. // Every blit that resolves a multisample SOURCE into a single-sample destination // returned above - the depth/stencil arm at the top of this lambda through - // ResolveWireDepthStencil, the colour arm below it through its resolve scratch - + // ResolveWireDepthStencil, the color arm below it through its resolve scratch - // and both of those now carry their own scale and flip. So the samples of the two // sides can only differ here by the DESTINATION being multisampled, which is the // shape this arm declines rather than the one it performs. @@ -2423,7 +2423,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; const Bool depthArmTakesShape = planar && layersInRange && (props.optimalTilingFeatures & depthPassFeatures) == depthPassFeatures; - // The colour arm's shape (the two shader shapes are explained at the colour arm below). + // The color arm's shape (the two shader shapes are explained at the color arm below). const Bool colour = resource->aspect == VK_IMAGE_ASPECT_COLOR_BIT; // The shader arm samples through a sampler2D and writes a vec4, which is what // BlitWireColorImage's own float check enforces; naming it here rather than letting the @@ -2459,7 +2459,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // P7 wave 2-B, CONTRACT-P7 §5.1 (A): THE DEPTH ARM, and it is first because a // depth format without BLIT_DST is the ordinary case, not the exotic one - // VK_FORMAT_FEATURE_BLIT_DST is optional for depth and plenty of devices decline - // it. Before this package the whole branch below was colour-only, so such a + // it. Before this package the whole branch below was color-only, so such a // texture reached `mipmap-shader-format-or-shape` on its very first disjunction // while the monolith arm quietly generated the chain with a shader. // @@ -2511,7 +2511,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // TWO SHADER SHAPES, not one. The arm that was here rendered STRAIGHT INTO the // next level, which needs the image to have been created with // COLOR_ATTACHMENT usage - and a texture whose format the device refuses as a - // colour attachment never gets that bit (VkTextureManager.cpp:2156-2160), so + // color attachment never gets that bit (VkTextureManager.cpp:2156-2160), so // every sampled-only texture without BLIT support fell into the refusal rather // than into a fallback. When the FORMAT can be rendered and only the IMAGE // cannot, an owned scratch attachment of the destination level's size renders diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireMultisampleResolve.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireMultisampleResolve.cpp index 09a93fb7..ab152f61 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireMultisampleResolve.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireMultisampleResolve.cpp @@ -13,7 +13,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // GL shader compiler. It is WireDepthMipmap.cpp's pass with the box filter taken out and a // sample index put in. // - // WHY THIS FILE EXISTS. vkCmdResolveImage is COLOUR ONLY. The one way Vulkan resolves a depth + // WHY THIS FILE EXISTS. vkCmdResolveImage is COLOR ONLY. The one way Vulkan resolves a depth // or stencil aspect without a shader is a render pass with a depth/stencil resolve attachment, // which needs VK_KHR_create_renderpass2 and VK_KHR_depth_stencil_resolve - and until this // package a device without either killed the session at @@ -138,7 +138,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkFramebuffer framebuffer = VK_NULL_HANDLE; VK_VERIFY(vkCreateFramebuffer(m_device, &framebufferInfo, nullptr, &framebuffer)); - // Each in-flight pass owns its descriptor set, for the colour blit's reason: updating a + // Each in-flight pass owns its descriptor set, for the color blit's reason: updating a // cached set would rewrite the source view of an older queued pass. VkDescriptorPool descriptorPool = VK_NULL_HANDLE; VkDescriptorSet descriptorSet = VK_NULL_HANDLE; diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WirePlaceholderKey.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/WirePlaceholderKey.h index 22379a73..5c889d4f 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WirePlaceholderKey.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WirePlaceholderKey.h @@ -37,7 +37,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // Every private placeholder is its own vkCreateImage + vkAllocateMemory, freed only at Shutdown. // (shape, unit) bounds them by shapes x kMGPipeMaxImageUnits, and a peer rotating formats and - // targets across the units could still walk that towards maxMemoryAllocationCount (4096 is the + // targets across the units could still walk that toward maxMemoryAllocationCount (4096 is the // spec minimum). So past this many, a NEW (shape, unit) takes its shape's SHARED placeholder - the // pre-fix aliasing, logged once by the caller - instead of another allocation; a unit that already // has its private placeholder keeps it. Two per unit is far past any real program. diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireYuvImage.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireYuvImage.cpp index d25e9303..c49ee68b 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/WireYuvImage.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/WireYuvImage.cpp @@ -15,9 +15,9 @@ namespace MobileGL::MG_Backend::DirectVulkan { // texture's image: the texture keeps its own RGBA8 level 0 (VkTextureManager::SyncWireTextureShape) // and, at its first use in each frame, the image is CONVERTED into it here - the image's // AHardwareBuffer imported with its external format, sampled through an immutable sampler that - // carries a VkSamplerYcbcrConversion built from the import's colour hints, one triangle over the + // carries a VkSamplerYcbcrConversion built from the import's color hints, one triangle over the // target. Zero CPU copies for an image this server allocated; a foreign one (a video decoder's - // buffer) is first brought up to date by the registry's labelled CPU copy (RefreshForeign). + // buffer) is first brought up to date by the registry's labeled CPU copy (RefreshForeign). // // Why converted rather than sampled in place: a Y'CbCr conversion is an immutable sampler, which // lives in the descriptor set layout and therefore in every application pipeline that samples the @@ -154,7 +154,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { // ---- the texture's import of the buffer, and the pipeline its conversion needs ---- auto* source = static_cast(resource.yuvSource.get()); if (source != nullptr && !(source->hints == hints)) { - // Re-imported with other colour hints: the conversion (and so the view) changes. + // Re-imported with other color hints: the conversion (and so the view) changes. auto retired = MakeUnique(); retired->yuvSource = std::move(resource.yuvSource); WireRetiredObjects objects{}; diff --git a/MobileGL/MG_Backend/Init.cpp b/MobileGL/MG_Backend/Init.cpp index 8a66de6a..55834e08 100644 --- a/MobileGL/MG_Backend/Init.cpp +++ b/MobileGL/MG_Backend/Init.cpp @@ -240,7 +240,7 @@ namespace MobileGL::MG_Backend { // a bit derived from `ActiveBackendType == ...` would keep claiming the capability // for a build, a flavour or a future backend whose table does not carry the arm - // which is exactly how 66 uploads were lost to a consumer bit that nobody could - // have honoured. `g_resourceOpsAtStep2` is the pointer this function just pinned, + // have honored. `g_resourceOpsAtStep2` is the pointer this function just pinned, // and step 5 already refuses a run where that pointer was swapped underneath us, so // reading the arm off it means the published bit and the table that has to answer // for it cannot come apart. diff --git a/MobileGL/MG_Backend/MGPipe/PipeInputs.cpp b/MobileGL/MG_Backend/MGPipe/PipeInputs.cpp index 958076f3..939b0145 100644 --- a/MobileGL/MG_Backend/MGPipe/PipeInputs.cpp +++ b/MobileGL/MG_Backend/MGPipe/PipeInputs.cpp @@ -353,11 +353,11 @@ namespace MobileGL::MG_Pipe { void MGPipeServerBlockNoteIdentity() { // D10: THE WIDER PREDICATE, and the narrow one was a latent crash rather than a missing - // optimisation. Gated on the REHEARSAL, this early-returned for the whole life of a + // optimization. Gated on the REHEARSAL, this early-returned for the whole life of a // spawn server - because that knob is off by default and nothing in the spawn shape // turns it on - so the server's gPipeInputs->ContextIdentity() stayed nullptr forever. // DirectGLES' fb-slot memo compares that identity FIRST and with no generation, so a - // nullptr against its own nullptr initialiser reads as a CACHE HIT and hands out a slot + // nullptr against its own nullptr initializer reads as a CACHE HIT and hands out a slot // that was never filled. `st` lands the named Fatal at that site; this is the gate that // stops it being reachable in the first place. if (!MGPipeBlocksAreDistinct()) return; @@ -366,7 +366,7 @@ namespace MobileGL::MG_Pipe { // served-context clock: MGPipeApplierContextSerial moves exactly when the served // context does (MGPipeApplierReset), which is all the backends' per-context memo keys // ask of an identity. The odd-encoding keeps the token non-null at serial 0: a null - // identity reads as a hit against DirectGLES' zero-initialised fb-slot memo cache and + // identity reads as a hit against DirectGLES' zero-initialized fb-slot memo cache and // hands out a null slot - an unnamed crash where the rehearsal exists to produce a // named one. const Uint64 serial = MGPipeApplierContextSerial(); diff --git a/MobileGL/MG_Backend/MGPipe/PipeInputs.h b/MobileGL/MG_Backend/MGPipe/PipeInputs.h index 7c7d4e34..414e9bc0 100644 --- a/MobileGL/MG_Backend/MGPipe/PipeInputs.h +++ b/MobileGL/MG_Backend/MGPipe/PipeInputs.h @@ -227,7 +227,7 @@ namespace MobileGL::MG_Pipe { // such a verb is a BARRIER_PULLED read counted rather than Fatal, and only there is a // sticky forward a residual pull. PipeApplier::LeaveApplier must clear it after every // record: a server process has no client half to do it, so the flag would stay set and - // later reads (InvalidateCompileEnv during another context's backend initialisation) + // later reads (InvalidateCompileEnv during another context's backend initialization) // would be judged against the last verb's mask. Bool ServerStampedVerb() const { return m_serverStampedVerb; } @@ -622,7 +622,7 @@ namespace MobileGL::MG_Pipe { // them with handle tables and callbacks. // They carry no MGP_INPUT_CHECK / MGP_INPUT_VERIFY_READ (the declared exception to // P1 brief D4's "every accessor body"): a forward is a live call, not a stored value, - // and InvalidateCompileEnv is reached from backend initialisation before any verb has + // and InvalidateCompileEnv is reached from backend initialization before any verb has // filled, where a check would be Fatal{...@} on every start. Their sticky stamp // is therefore consulted by no accessor; the tests pin it through // MGPipeInputFieldIsFresh directly. @@ -689,7 +689,7 @@ namespace MobileGL::MG_Pipe { // MGPipeServerSetContextLive's flag. In the block, not in a process global, because the // in-process display server runs several sessions at once and each has its own served // context: one session's teardown or eglMakeCurrent(NO_CONTEXT) must not mark a - // neighbour's context dead mid-frame (P14; the per-thread block resolution below is + // neighbor's context dead mid-frame (P14; the per-thread block resolution below is // what makes this the calling session's). Bool m_serverContextLive = false; MGPipeVerb m_currentVerb = MGPipeVerb::kVerbCount; @@ -896,7 +896,7 @@ namespace MobileGL::MG_Pipe { // from MGPipeApplierContextSerial() - the server's own served-context clock, which is what // moves when the served context does. Without it the server block's ContextIdentity() would // stay nullptr, and DirectGLES' fb-slot memo cache compares identity FIRST (a nullptr - // against its own nullptr initialiser reads as a hit and hands out a null slot): an + // against its own nullptr initializer reads as a hit and hands out a null slot): an // unnamed crash where the rehearsal exists to produce a named one. A no-op with the // rehearsal off, so the client's per-verb SetIdentity keeps owning the shared block there. void MGPipeServerBlockNoteIdentity(); diff --git a/MobileGL/MG_Backend/Record/RecordVerbSink.cpp b/MobileGL/MG_Backend/Record/RecordVerbSink.cpp index 5caee8ec..6745806f 100644 --- a/MobileGL/MG_Backend/Record/RecordVerbSink.cpp +++ b/MobileGL/MG_Backend/Record/RecordVerbSink.cpp @@ -98,9 +98,9 @@ namespace MobileGL::MG_Record { break; default: // A value class outside the three is a wire fault, not a fallback: all three - // representations of a clear colour are numerically populated by the frontend + // representations of a clear color are numerically populated by the frontend // and only this field says which one the backend must use, so guessing renders - // a plausible wrong colour. + // a plausible wrong color. MG_Pipe::MGPipeProtocolFatalAt("MGPClear::ValueClass", clear.ValueClass, 3); } break; @@ -227,7 +227,7 @@ namespace MobileGL::MG_Record { // scatters it per its own GL_PACK_* state, so a DstSize that disagrees with the tight // extent (a client that sized its destination with pack padding) is logged and the tight // extent this side owns is read and posted - never the client's number, so a wrong - // DstSize cannot make this a short read into uninitialised scratch. F2's first PH-3 draft + // DstSize cannot make this a short read into uninitialized scratch. F2's first PH-3 draft // refused the mismatch instead, which broke the ID-49 control // (ServerLoopEglTest.AReadPixelsReplyIsTheTightExtentWhateverDstSizeTheClientSent); the // bound above is what PH-3 needs and it does not depend on DstSize. diff --git a/MobileGL/MG_Backend/Record/StagedShadow.h b/MobileGL/MG_Backend/Record/StagedShadow.h index e9c00f6c..7fb32f16 100644 --- a/MobileGL/MG_Backend/Record/StagedShadow.h +++ b/MobileGL/MG_Backend/Record/StagedShadow.h @@ -22,7 +22,7 @@ // INVALIDATE_RANGE clobbered GPU-written data - an SSBO counter beside the app's SubData - with // stale shadow bytes (FlushPendingRangesFrom, ManagersBuffers.cpp). Tier 1's INVALIDATE_RANGE is an ASSERTION that // the old bytes are dead, so declaring bytes covered that nothing staged is not a missing -// optimisation, it is a silent data loss. The coverage set below is therefore exact, and a +// optimization, it is a silent data loss. The coverage set below is therefore exact, and a // drain that reaches outside it is Fatal rather than a re-read of whatever happens to be there. // // WHY IT IS A HEADER AND NOT A BLOCK INSIDE Managers.cpp. Two reasons, and the second is the @@ -55,7 +55,7 @@ namespace MobileGL::MG_Record { // P14: WHOSE STAGED BYTES ARE THESE? The two server stores below are one per process, but the // in-process display server serves several sessions in that process at once, and a session's // end (DestroyEGLContext's OnBackendContextDestroyed) used to DropAll() them - every live - // neighbour's declared texture levels and buffer shadows with it. The neighbour's next upload + // neighbor's declared texture levels and buffer shadows with it. The neighbor's next upload // into a texture it had declared long ago then read as "resource_subdata arrived before the // server declared texture level", a Fatal that took the whole display process (and so every // session in it) down. The texture store is also keyed by the client's {slot, gen}, which two diff --git a/MobileGL/MG_Backend/Record/StagedTextureStore.h b/MobileGL/MG_Backend/Record/StagedTextureStore.h index d71325c6..9d1a83c4 100644 --- a/MobileGL/MG_Backend/Record/StagedTextureStore.h +++ b/MobileGL/MG_Backend/Record/StagedTextureStore.h @@ -61,7 +61,7 @@ // that lets the sync read - the set is complete exactly when every piece has landed, and a level // with a hole in it is Fatal{StageSnapshotTooNarrow}: the same words as the buffer half, for the // same reason, because those bytes have never existed on this side and inventing them is silent -// data loss rather than a missing optimisation. THE QUESTION IS "IS THE RANGE THE READER ASKS +// data loss rather than a missing optimization. THE QUESTION IS "IS THE RANGE THE READER ASKS // FOR COVERED", not "is the level the size the client meant": no format crosses the wire, so a // leading run that already reaches the image's high-water mark reads as complete when later // pieces are still missing - unreachable, because nothing reads between the pieces of one verb, @@ -502,7 +502,7 @@ namespace MobileGL::MG_Record { // The calling thread's SESSION's levels (every group of it - the callers are a session's // context teardown and its applier release), or every level on a thread that is no - // session's. A live neighbour session's declared levels are not this caller's to drop: + // session's. A live neighbor session's declared levels are not this caller's to drop: // that is the P14 Fatal StagedShadow.h's StagedBucket describes. void DropAll() { if (!m_any.load(std::memory_order_acquire)) return; diff --git a/MobileGL/MG_Backend/SharedImageTypes.h b/MobileGL/MG_Backend/SharedImageTypes.h index f0d9babe..e397b9b9 100644 --- a/MobileGL/MG_Backend/SharedImageTypes.h +++ b/MobileGL/MG_Backend/SharedImageTypes.h @@ -10,7 +10,7 @@ #include namespace MobileGL::MG_Backend { - // SHARED IMAGES: server-allocated colour + // SHARED IMAGES: server-allocated color // buffers exported to clients as dma-buf descriptors. // // The server-side view of one image, as a backend sees it: `NativeBuffer` is the image's @@ -42,7 +42,7 @@ namespace MobileGL::MG_Backend { }; // An import of a two-plane (YUV) dma-buf: where its planes are in the one descriptor, and - // EGL_EXT_image_dma_buf_import's colour hints (0 = not given). + // EGL_EXT_image_dma_buf_import's color hints (0 = not given). struct SharedImageImportLayout { Uint32 PlaneCount = 1; Uint32 Offset[2] = {0, 0}; diff --git a/MobileGL/MG_Benchmark/Driver/DriverBench.c b/MobileGL/MG_Benchmark/Driver/DriverBench.c index 40df6b8d..e0d9f2fd 100644 --- a/MobileGL/MG_Benchmark/Driver/DriverBench.c +++ b/MobileGL/MG_Benchmark/Driver/DriverBench.c @@ -245,7 +245,7 @@ static void bench_multi_draw_elements_base_vertex(GLenum mode, const GLsizei* co * glFinish and glFlush as no-ops (MG_Impl/GLImpl/Exporting/Definitions.cpp), * so a glFinish-paced loop would time only the CPU-side submit on a MobileGL * backend while timing submit-plus-GPU on the native driver - the two numbers - * would not describe the same work. A sync object is honoured by every stack + * would not describe the same work. A sync object is honored by every stack * measured here. */ typedef void (*case_fn)(int frame, long a, long b); diff --git a/MobileGL/MG_Benchmark/Driver/DriverBenchCases.inc b/MobileGL/MG_Benchmark/Driver/DriverBenchCases.inc index 17e16c8c..eefc3a56 100644 --- a/MobileGL/MG_Benchmark/Driver/DriverBenchCases.inc +++ b/MobileGL/MG_Benchmark/Driver/DriverBenchCases.inc @@ -605,7 +605,7 @@ static void case_mc_use_program(int frame, long a, long b) { /* ---- the case table both harnesses iterate -------------------------------- * a/b are the case's own knobs; opsPerFrame is what one bench frame is - * normalised by, so ns_per_op compares across renderers. The mc_* rates are + * normalized by, so ns_per_op compares across renderers. The mc_* rates are * the per-frame call counts measured from the captured traces. */ typedef void (*bench_case_fn)(int frame, long a, long b); diff --git a/MobileGL/MG_Benchmark/ShaderCache/TranslationCacheBench.cpp b/MobileGL/MG_Benchmark/ShaderCache/TranslationCacheBench.cpp index 18a53e5d..7cb2579f 100644 --- a/MobileGL/MG_Benchmark/ShaderCache/TranslationCacheBench.cpp +++ b/MobileGL/MG_Benchmark/ShaderCache/TranslationCacheBench.cpp @@ -19,7 +19,7 @@ // at glCompileShader - a different entry point from the one L1 // memoizes - and fresh shader objects meant ShaderCompileAdoptionMap // could not hand the earlier parse over either. L1c is what closed -// that: the compile half of the memo recognises each stage's source +// that: the compile half of the memo recognizes each stage's source // and publishes its verdict without parsing, so on a hit this case now // constructs no glslang object at all. // @@ -405,7 +405,7 @@ BENCHMARK(BM_EsslTranspile_CacheOn)->Arg(0)->Arg(120)->Unit(benchmark::kMicrosec // shows up here and nowhere else. // // The distinct fragment sources also churn both front-end levels through their FIFO caps, -// which is the eviction behaviour a real shaderpack load produces; over a long run the +// which is the eviction behavior a real shaderpack load produces; over a long run the // constant vertex entry is occasionally evicted by that churn and re-inserted, so the L1c // hit rate reported below is high but not exactly 1.0 per iteration. namespace { diff --git a/MobileGL/MG_Benchmark/Transpile/TranspileProfile.cpp b/MobileGL/MG_Benchmark/Transpile/TranspileProfile.cpp index 678d1fa5..b8b60da2 100644 --- a/MobileGL/MG_Benchmark/Transpile/TranspileProfile.cpp +++ b/MobileGL/MG_Benchmark/Transpile/TranspileProfile.cpp @@ -19,7 +19,7 @@ // zero-pass Optimizer::Run and a bare BuildModule on the same binary, so the FIXED // parse/serialize overhead can be separated from the work the passes actually do. It also // runs the same pass set merged onto ONE Optimizer, which is the saving a merged chain -// would realise. +// would realize. // // Measurement only: it links MobileGL_s and drives the public ShaderCompiler API, so it // needs no GL context and no driver. The driver's own glCompileShader/glLinkProgram is @@ -746,7 +746,7 @@ void main() { Emit(name, "program", "glslang.GlslangToSpv (both stages)", "frontend", 0, inner); } - // ---- build the artefacts every later measurement runs against ---- + // ---- build the artifacts every later measurement runs against ---- BuiltProgram built; { auto shaders = ParseBoth(vsPre, fsPre, env); diff --git a/MobileGL/MG_Gbm/MobileGLGbm.cpp b/MobileGL/MG_Gbm/MobileGLGbm.cpp index c6529be7..e7e48fce 100644 --- a/MobileGL/MG_Gbm/MobileGLGbm.cpp +++ b/MobileGL/MG_Gbm/MobileGLGbm.cpp @@ -7,7 +7,7 @@ // End of Source File Header // mobilegl_gbm.so: a GBM backend (the loader's backend ABI, gbm_backend_abi.h) whose buffer -// objects are MobileGL shared images - colour buffers the MobileGL server allocates and exports +// objects are MobileGL shared images - color buffers the MobileGL server allocates and exports // as dma-bufs. Selected with // GBM_BACKEND=mobilegl; the loader then finds /mobilegl_gbm.so on its backend path. // @@ -54,7 +54,7 @@ namespace { constexpr uint64_t kModifierLinear = 0; constexpr uint64_t kModifierInvalid = 0x00ffffffffffffffull; - // Usages no shared image can honour: a CPU-written cursor (bo_write), a guaranteed-linear + // Usages no shared image can honor: a CPU-written cursor (bo_write), a guaranteed-linear // layout, protected content. Scanout/rendering/texturing are accepted - every caller of // gbm_bo_create passes them, and a shared image serves all three. constexpr uint32_t kRefusedUsage = GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE | GBM_BO_USE_LINEAR | GBM_BO_USE_PROTECTED; diff --git a/MobileGL/MG_Impl/EGLImpl/EGLPlatformExtensions.h b/MobileGL/MG_Impl/EGLImpl/EGLPlatformExtensions.h index 96cd293c..18c4f49d 100644 --- a/MobileGL/MG_Impl/EGLImpl/EGLPlatformExtensions.h +++ b/MobileGL/MG_Impl/EGLImpl/EGLPlatformExtensions.h @@ -36,7 +36,7 @@ namespace MobileGL::MG_Impl::EGLImpl { "EGL_MESA_platform_surfaceless" MOBILEGL_PLATFORM_WAYLAND_EXTENSIONS; // The display list again, with the dma-buf import a backend with shared images has (a split // client: the server allocates the images and names the descriptors that come back). A - // monolith has no allocator to recognise a dma-buf with, so it never advertises these. The + // monolith has no allocator to recognize a dma-buf with, so it never advertises these. The // same server answers the buffer age of its surfaces and takes swap damage to its presents. inline constexpr const char* kDisplayExtensionStringWithSharedImages = "EGL_KHR_create_context EGL_KHR_surfaceless_context EGL_KHR_no_config_context EGL_EXT_platform_base " diff --git a/MobileGL/MG_Impl/EGLImpl/WaylandWindow.h b/MobileGL/MG_Impl/EGLImpl/WaylandWindow.h index 66dd364a..ace06f47 100644 --- a/MobileGL/MG_Impl/EGLImpl/WaylandWindow.h +++ b/MobileGL/MG_Impl/EGLImpl/WaylandWindow.h @@ -50,7 +50,7 @@ namespace MobileGL::MG_Impl::EGLImpl::Wayland { inline constexpr EGLenum kPlatformWayland = 0x31D8; // Whether a display is a Wayland one: asked for as EGL_PLATFORM_WAYLAND, or (eglGetDisplay with - // no platform) a native display that is a wl_display - recognised the way EGL loaders usually do, by its + // no platform) a native display that is a wl_display - recognized the way EGL loaders usually do, by its // first word being libwayland-client's wl_display_interface (or, for an application with its // own copy of libwayland, an interface named "wl_display"). Bool IsWaylandDisplay(Uint64 nativeDisplay, EGLenum platform); diff --git a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp index 436196bc..ffeeb998 100644 --- a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp @@ -412,7 +412,7 @@ namespace MobileGL::MG_Impl::GLImpl { break; case GL_BUFFER_ACCESS_FLAGS: // The MapBufferRange flags verbatim; glMapBuffer's access enum has already been - // normalised into the same bits. Zero while the buffer is not mapped. + // normalized into the same bits. Zero while the buffer is not mapped. *params = bufferObject->IsMapped() ? static_cast(MG_Util::ConvertBufferMappingAccessToGLEnum( bufferObject->GetMappingAccess())) : 0; diff --git a/MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.cpp b/MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.cpp index 5f7a6d7e..4193fdab 100644 --- a/MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.cpp +++ b/MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.cpp @@ -90,7 +90,7 @@ namespace MobileGL::MG_Impl::GLImpl { } // Whether `name` currently names an object of `identifier`'s type. GL 4.6 core 20.5 makes - // labelling something that does not exist INVALID_VALUE, and every type KHR_debug lists + // labeling something that does not exist INVALID_VALUE, and every type KHR_debug lists // has a frontend name check - so this is answered exactly rather than waved through. // GL_DISPLAY_LIST is deliberately absent: it exists only in the compatibility profile, // which MobileGL does not expose, so it falls to the INVALID_ENUM path below. diff --git a/MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.h b/MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.h index 5b521319..3851e0d7 100644 --- a/MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.h +++ b/MobileGL/MG_Impl/GLImpl/Debug/GL_Debug.h @@ -19,7 +19,7 @@ namespace MobileGL::MG_Impl::GLImpl { // * glObjectLabel names a FRONTEND object. MobileGL's texture 5 is not the ES driver's // texture 5 (and under DirectVulkan it is not a driver object at all), so forwarding the // pair verbatim would label an unrelated object or a nonexistent one - worse than not - // labelling. + // labeling. // * A debug GROUP is only meaningful if it brackets the commands the application issued // inside it. Neither backend emits its work at the moment the GL call arrives: DirectGLES // defers and reorders state sync and uploads around draws, and DirectVulkan is usually not diff --git a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp index 6e581431..b44e7edb 100644 --- a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp +++ b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp @@ -204,7 +204,7 @@ namespace MobileGL::MG_Impl::GLImpl { // Draws without a geometry stage write exactly the primitives they assemble, // clamped by the capture buffers' remaining capacity (a full buffer stops // recording whole primitives, which is what PRIMITIVES_WRITTEN reports). - // Geometry amplification is not modelled here. + // Geometry amplification is not modeled here. static void AccountTransformFeedbackPrimitives(GLenum mode, GLsizei count) { if (!MG_State::pGLContext->IsTransformFeedbackActive()) return; // A paused span captures nothing, so a draw made while paused contributes to diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp index 444d64e3..3666b9d3 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.cpp @@ -128,7 +128,7 @@ namespace MobileGL::MG_Impl::GLImpl { // because a capability recorded for one of them says nothing about the others: DirectGLES // decides each target's substitution against that target's own probe, and a buffer texture // never gets one at all. This is also where the three-channel widening becomes visible to - // the application - a GL_RGB8_SNORM colour attachment on a driver with no renderable + // the application - a GL_RGB8_SNORM color attachment on a driver with no renderable // three-channel format answers COMPLETE because the backend stores it as GL_RGBA16F and // recorded FramebufferRenderable in CaveatCaps. Bool IsColorInternalFormatRenderable(TextureInternalFormat format, SizeT capabilityTargetIndex) { @@ -502,9 +502,9 @@ namespace MobileGL::MG_Impl::GLImpl { if (!FramebufferImpl::ValidateColorAttachmentInRange(attachmentType, functionName)) return false; // "An INVALID_OPERATION error is generated if zero is bound to target." MobileGL keeps // a real FramebufferObject for framebuffer 0, so a null test can never see this - the - // object is always there, and framebuffer 0 has to be recognised by identity instead, + // object is always there, and framebuffer 0 has to be recognized by identity instead, // the same comparison DrawBuffers_State makes. Without this an attach onto the default - // framebuffer silently REPLACED its colour attachment, permanently desynchronising it + // framebuffer silently REPLACED its color attachment, permanently desynchronising it // from what the swapchain keeps publishing. const auto& defaultFramebufferInfo = FramebufferImpl::pDefaultFramebufferInfo; if (!framebufferObject || @@ -568,12 +568,12 @@ namespace MobileGL::MG_Impl::GLImpl { // shorthand for attaching the same image to both halves (GL 4.6 core 9.2.6), so // whether glFramebufferTexture made it LAYERED is a property of the call, not of // which half is being recorded - and dropping it here (the parameter defaults to - // false) recorded a non-layered depth/stencil attachment beside a layered colour + // false) recorded a non-layered depth/stencil attachment beside a layered color // one for every layered target. That is an inconsistent framebuffer by 9.4.1's // own rule, and downstream it means the depth/stencil attachment covers layer 0 // alone: DirectVulkan built its view with layerCount 1 under a framebuffer // declaring N layers (VUID-VkFramebufferCreateInfo-flags-04535), and DirectGLES - // attached one layer of it beside a layered colour target, which the driver + // attached one layer of it beside a layered color target, which the driver // answers with GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS - every draw silently // produced nothing. This is the shape // texture_cube_map_array.stencil_attachments_*_layered and @@ -1654,7 +1654,7 @@ namespace MobileGL::MG_Impl::GLImpl { } // Everything above is the spec's error set and is answered for every target and every layer - // on every backend. Whether the attachment can actually be honoured is a backend question: + // on every backend. Whether the attachment can actually be honored is a backend question: // DirectGLES hands the layer to glFramebufferTextureLayer and renders to it, while // DirectVulkan maps a GL layer onto a Vulkan array layer with no notion of a 3D depth slice, // so a slice lands outside the image and the renderer asserts on the clear. Letting it @@ -1904,7 +1904,7 @@ namespace MobileGL::MG_Impl::GLImpl { MG_State::pGLContext->RecordError( isMultiBufferName ? ErrorCode::InvalidOperation : ErrorCode::InvalidEnum, MakeUnique("MG_Impl/GLImpl", caller, - std::format("`src` = {} does not name a single readable colour buffer.", + std::format("`src` = {} does not name a single readable color buffer.", MG_Util::ConvertGLEnumToString(src)))); return; } @@ -1918,7 +1918,7 @@ namespace MobileGL::MG_Impl::GLImpl { // Naming a buffer the other kind of framebuffer has is INVALID_OPERATION rather than // INVALID_ENUM (GL 4.6 core 17.4.1) - the name is accepted, this framebuffer just has no - // such colour buffer. + // such color buffer. if (isDefaultFBO && attType != FramebufferAttachmentType::None && (attType < FramebufferAttachmentType::FrontLeft || attType > FramebufferAttachmentType::BackRight)) { MG_State::pGLContext->RecordError( @@ -2060,7 +2060,7 @@ namespace MobileGL::MG_Impl::GLImpl { // Which buffers the integer clears accept is narrower than the float one, and differs between // them: signed values can clear COLOR or STENCIL, unsigned only COLOR (GL 4.6 core 17.4.3.1). - // Only the colour buffer is indexed; a stencil clear names the single stencil buffer, so any + // Only the color buffer is indexed; a stencil clear names the single stencil buffer, so any // drawbuffer other than 0 is out of range rather than merely unused. Bool ValidateNamedClearIntegerv_State(GLenum buffer, GLint drawbuffer, const void* value, Bool allowStencil, const char* caller) { @@ -2121,7 +2121,7 @@ namespace MobileGL::MG_Impl::GLImpl { // glInvalidateFramebuffer and its three siblings only grant the implementation permission to // throw the named attachments' contents away - "become undefined" is satisfied by keeping them // - so MobileGL validates the call and leaves the contents alone. Discarding is a bandwidth - // optimisation that would need a backend dependency; it can be added later without changing + // optimization that would need a backend dependency; it can be added later without changing // what any of these entry points promise. The conformance tests exercise the validation, which // is the part that was missing. Bool ValidateInvalidateAttachments_State(const SharedPtr& framebuffer, @@ -2144,7 +2144,7 @@ namespace MobileGL::MG_Impl::GLImpl { if (isDefaultFramebuffer) { switch (attachment) { // The by-name forms name the default framebuffer's buffers the way - // glClearNamedFramebuffer does, with COLOR standing for the colour buffer, while + // glClearNamedFramebuffer does, with COLOR standing for the color buffer, while // the target forms use the individual FRONT_LEFT/BACK_RIGHT tokens. Both spellings // reach here, so both are accepted (GL 4.6 core 17.4.4). case GL_COLOR: @@ -3341,7 +3341,7 @@ namespace MobileGL::MG_Impl::GLImpl { return false; } // Depth and stencil have no meaningful interpolation, so GL_LINEAR is rejected outright - // rather than downgraded - even when the mask also carries the colour bit. + // rather than downgraded - even when the mask also carries the color bit. if (filter == GL_LINEAR && (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) { MG_State::pGLContext->RecordError( ErrorCode::InvalidOperation, diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/Validators.cpp b/MobileGL/MG_Impl/GLImpl/Framebuffer/Validators.cpp index a24e711f..b48b8e39 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/Validators.cpp +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/Validators.cpp @@ -75,7 +75,7 @@ namespace MobileGL::MG_Impl::GLImpl::FramebufferImpl { ErrorCode::InvalidOperation, MakeUnique( "MG_Impl/GLImpl/FramebufferImpl", caller, - std::format("Colour attachment {} is beyond GL_MAX_COLOR_ATTACHMENTS ({}).", colorIndex, limit))); + std::format("Color attachment {} is beyond GL_MAX_COLOR_ATTACHMENTS ({}).", colorIndex, limit))); return false; } return true; diff --git a/MobileGL/MG_Impl/GLImpl/Framebuffer/Validators.h b/MobileGL/MG_Impl/GLImpl/Framebuffer/Validators.h index 513c0c79..d3e6fa06 100644 --- a/MobileGL/MG_Impl/GLImpl/Framebuffer/Validators.h +++ b/MobileGL/MG_Impl/GLImpl/Framebuffer/Validators.h @@ -16,7 +16,7 @@ namespace MobileGL::MG_Impl::GLImpl::FramebufferImpl { Bool ValidateFramebufferAttachmentType(FramebufferAttachmentType attachment); // GL_COLOR_ATTACHMENTn is a token per n up to 31, but only the first GL_MAX_COLOR_ATTACHMENTS of // them name an attachment point of a framebuffer object; the rest are INVALID_OPERATION for the - // attaching entry points (GL 4.6 core 9.2.7). Non-colour attachments pass through unchanged. + // attaching entry points (GL 4.6 core 9.2.7). Non-color attachments pass through unchanged. Bool ValidateColorAttachmentInRange(FramebufferAttachmentType attachment, const char* caller); Bool ValidateRenderbufferTarget(RenderbufferTarget target); Bool ValidateRenderbufferName(Uint index, Bool allowZero = true); diff --git a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp index 90fdfc02..473fe5e3 100644 --- a/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp +++ b/MobileGL/MG_Impl/GLImpl/Getter/GL_Getter.cpp @@ -152,7 +152,7 @@ namespace MobileGL::MG_Impl::GLImpl { // glGetSubroutineIndex / glUniformSubroutinesuiv, only the program-interface enum // plumbing. These are answered - with the GL 4.5 core minimums - because the conformance // suite queries them before it checks for the feature and an INVALID_ENUM both leaves the - // caller reading its own uninitialised stack slot and strands an error for the next + // caller reading its own uninitialized stack slot and strands an error for the next // unrelated call to trip over. The extension is deliberately NOT advertised, so the // numbers are a table entry, not a capability claim. constexpr GLint kFrontendMaxSubroutines = 256; @@ -1542,7 +1542,7 @@ namespace MobileGL::MG_Impl::GLImpl { // // The POINTER-valued macro, so the init-statement below is unchanged in a pull // build and G1 cannot see this edit: the Bool-valued spelling moved this - // function by -150 bytes for no behavioural reason at all. + // function by -150 bytes for no behavioral reason at all. if (const auto getGpuTimestampNs = MGL_BACKEND_SLOT_PTR_CAP(GetGpuTimestampNs, MG_Pipe::kCapTimerQuery)) { MGP_FILL(GetGpuTimestampNs); @@ -2584,7 +2584,7 @@ namespace MobileGL::MG_Impl::GLImpl { // // The POINTER-valued macro, so the init-statement below is unchanged in a pull // build and G1 cannot see this edit: the Bool-valued spelling moved this - // function by -150 bytes for no behavioural reason at all. + // function by -150 bytes for no behavioral reason at all. if (const auto getGpuTimestampNs = MGL_BACKEND_SLOT_PTR_CAP(GetGpuTimestampNs, MG_Pipe::kCapTimerQuery)) { MGP_FILL(GetGpuTimestampNs); diff --git a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp index 14712a73..5c4a80d3 100644 --- a/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp +++ b/MobileGL/MG_Impl/GLImpl/Program/GL_Program.cpp @@ -573,7 +573,7 @@ namespace MobileGL::MG_Impl::GLImpl { } GLuint CreateShader_State(GLenum type) { - // GL 4.6 core 7.1: shaderType is an enum, so an unrecognised one is INVALID_ENUM (it + // GL 4.6 core 7.1: shaderType is an enum, so an unrecognized one is INVALID_ENUM (it // used to be documented as INVALID_VALUE). The check has to happen HERE: the state // layer hands out a name for ShaderStage::Unknown just as happily as for a real // stage, so the old "shaderId == 0 means bad type" test could never fire and an @@ -3324,7 +3324,7 @@ namespace MobileGL::MG_Impl::GLImpl { void GetProgramResourceiv(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params) { // Every early-out below reports "nothing was written", and it has to say so before it can - // take one: callers legitimately leave *length uninitialised and then loop to it. The CTS + // take one: callers legitimately leave *length uninitialized and then loop to it. The CTS // does exactly that (gl4cProgramInterfaceQueryTests.cpp:2172 declares `GLsizei length;` and // walks `for (i = 0; i < length; ++i)` over a 1000-entry stack array), so an untouched // *length turned every error path here into a stack overrun inside the caller - @@ -3414,7 +3414,7 @@ namespace MobileGL::MG_Impl::GLImpl { // already carries, so this is a rename of glGetProgramResourceiv's props onto the older // entry point's - and the two are required to agree, which is only true while both read the // same model. It was a silent stub: it wrote nothing, raised nothing, and left every probe - // reading its own uninitialised output. + // reading its own uninitialized output. static Bool TryMapActiveAtomicCounterBufferProp(GLenum pname, GLenum& outProp) { switch (pname) { case GL_ATOMIC_COUNTER_BUFFER_BINDING: @@ -3547,7 +3547,7 @@ namespace MobileGL::MG_Impl::GLImpl { // raise is one of theirs, raised at the point they would raise it. GLuint CreateShaderProgramv(GLenum type, GLsizei count, const GLchar* const* strings) { // GL 4.6 core 7.3: a negative count is INVALID_VALUE and is checked before anything - // is created, so a bad count never leaks a shader name. An unrecognised type is + // is created, so a bad count never leaks a shader name. An unrecognized type is // INVALID_ENUM, which CreateShader_State raises below. if (count < 0) { MG_State::pGLContext->RecordError( diff --git a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp index c2b266c7..aef060d1 100644 --- a/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp +++ b/MobileGL/MG_Impl/GLImpl/RenderState/GL_RenderState.cpp @@ -372,7 +372,7 @@ namespace MobileGL::MG_Impl::GLImpl { } // GL_EXT_fragment_shading_rate 14.X.1: the only error is a rate outside table X.1, and the - // state is left untouched by it. Whether the device can honour the rate is not an error - + // state is left untouched by it. Whether the device can honor the rate is not an error - // an unsupported rate is clamped at rasterization, which the backends leave to the driver. void ShadingRateEXT_State(GLenum rate) { const Uint8 packed = MGPackShadingRate(rate); diff --git a/MobileGL/MG_Impl/GLImpl/Sampler/GL_Sampler.cpp b/MobileGL/MG_Impl/GLImpl/Sampler/GL_Sampler.cpp index b3dd3cc5..edb75526 100644 --- a/MobileGL/MG_Impl/GLImpl/Sampler/GL_Sampler.cpp +++ b/MobileGL/MG_Impl/GLImpl/Sampler/GL_Sampler.cpp @@ -57,7 +57,7 @@ namespace MobileGL::MG_Impl::GLImpl { return; } // Via GLint in both integer spellings: a direct float -> GLuint cast of a negative value - // (GL_TEXTURE_MIN_LOD defaults to -1000) is undefined behaviour, while the two-step + // (GL_TEXTURE_MIN_LOD defaults to -1000) is undefined behavior, while the two-step // conversion is the well-defined modular one, and it is what the texture-side // GetTexParameterIuiv fallback does. const GLint asInt = static_cast(value); @@ -86,7 +86,7 @@ namespace MobileGL::MG_Impl::GLImpl { case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_LOD_BIAS: return true; - // Four components, and GL puts no range on them - a border colour outside [0,1] is + // Four components, and GL puts no range on them - a border color outside [0,1] is // clamped when a fixed-point format is sampled, not rejected here. The scalar readers // below would look at one component and invent an error. case GL_TEXTURE_BORDER_COLOR: @@ -182,7 +182,7 @@ namespace MobileGL::MG_Impl::GLImpl { const auto* values = (const GLfloat*)param; samplerObj->SetBorderColor(FloatVec4(values[0], values[1], values[2], values[3])); } else if (!isIntegerCommand) { - // glSamplerParameteriv: GL 4.6 core equation 2.2 into the FLOAT border colour. + // glSamplerParameteriv: GL 4.6 core equation 2.2 into the FLOAT border color. const auto* values = (const GLint*)param; samplerObj->SetBorderColor(FloatVec4(MG_Util::SignedNormalizedInt32ToFloat(values[0]), MG_Util::SignedNormalizedInt32ToFloat(values[1]), diff --git a/MobileGL/MG_Impl/GLImpl/Sync/GL_Sync.cpp b/MobileGL/MG_Impl/GLImpl/Sync/GL_Sync.cpp index bb1e213c..6136ce7d 100644 --- a/MobileGL/MG_Impl/GLImpl/Sync/GL_Sync.cpp +++ b/MobileGL/MG_Impl/GLImpl/Sync/GL_Sync.cpp @@ -167,7 +167,7 @@ namespace MobileGL::MG_Impl::GLImpl { void GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) { // GL 4.6 core 4.1: a negative bufSize is INVALID_VALUE, an unnamed sync is INVALID_VALUE - // and an unrecognised pname is INVALID_ENUM. All three used to leave glGetError() clean + // and an unrecognized pname is INVALID_ENUM. All three used to leave glGetError() clean // and write a plausible-looking zero, which is the one failure mode a caller cannot tell // apart from a real answer - GL_SYNC_STATUS legitimately answers GL_UNSIGNALED (0x9118), // but a mistyped pname answered a bare 0 that no query ever returns. diff --git a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp index 7e3de191..4a034df1 100644 --- a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp +++ b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp @@ -67,7 +67,7 @@ namespace MobileGL::MG_Impl::GLImpl { } // glTexParameteriv(GL_TEXTURE_BORDER_COLOR): GL 4.6 core 8.10 sends the components through - // equation 2.2 into the floating-point border colour. glGetTexParameteriv reverses it with + // equation 2.2 into the floating-point border color. glGetTexParameteriv reverses it with // equation 2.3; the two live in one header so they cannot drift apart. void SetTextureBorderColorFromInts(const SharedPtr& textureObject, const GLint* params) { @@ -582,7 +582,7 @@ namespace MobileGL::MG_Impl::GLImpl { // AT the category limit (BackendObject_DirectGLES's ProbeTextureSampleCounts) so its // head can never exceed it, and max() therefore always collapsed to the category // value. A format whose 4- and 2-sample probes fail inside a 4-sample category - a - // float colour format under EXT_color_buffer_float is the natural instance - was + // float color format under EXT_color_buffer_float is the natural instance - was // still accepted at 4, silently squeezed to 1 by ClampSamplesToBackendSupport, and // then reported as 4 by GL_TEXTURE_SAMPLES while glGetInternalformativ said 1. const Int probedMaxSamples = GetProbedMaxTextureSamples(textureTarget, textureInternalFormat); @@ -672,7 +672,7 @@ namespace MobileGL::MG_Impl::GLImpl { // Redefining level 0 of a texture that already had a base image drops the rest of the chain, // which is exactly what AllocateLevel used to do implicitly for every level. Keeping that - // behaviour for level 0 - and only for level 0 - is what makes the grow-only change safe: + // behavior for level 0 - and only for level 0 - is what makes the grow-only change safe: // any level-0 respecification leaves the chain in precisely the state it would have had // before, while an upload to level N no longer destroys the levels beneath it. // @@ -1002,7 +1002,7 @@ namespace MobileGL::MG_Impl::GLImpl { return true; } // GL 4.6 core 8.6: CopyTexSubImage* is not affected by pixel-store state or by a bound - // pack buffer, but the backend readback this borrows honours both. Neutralise them for the + // pack buffer, but the backend readback this borrows honors both. Neutralise them for the // duration of the read and put them back afterwards. class ScopedNeutralPackState { public: @@ -1203,7 +1203,7 @@ namespace MobileGL::MG_Impl::GLImpl { } // The six pnames a texture object shares with a sampler object carry an enum VALUE, and an - // unrecognised one is INVALID_ENUM. The texture path used to hand the value straight to + // unrecognized one is INVALID_ENUM. The texture path used to hand the value straight to // ConvertGLEnumToSamplerWrapMode / ...FilterMode and throw the Unknown away, so // glTexParameteri(GL_TEXTURE_WRAP_S, GL_RED) was silently accepted. Sampler objects have had // exactly this validator all along; calling it here rather than writing a second one is also @@ -1348,7 +1348,7 @@ namespace MobileGL::MG_Impl::GLImpl { // every setter reaches" - and MGPTextureParams takes MinLod, MaxLod and LodBias off that // object, so every glTexParameter that writes GL_TEXTURE_MIN_LOD / MAX_LOD / LOD_BIAS // landed on state nothing watched and the applier's record kept saying MinLod = 0. - // Wrong pixels, not a lost optimisation. + // Wrong pixels, not a lost optimization. // // THE HOOK IS HERE RATHER THAN ON BumpVersion because MG_State/GLState/SamplerState is // package C's after the tag; C.7 grants this file for exactly this class of path ("the @@ -1462,7 +1462,7 @@ namespace MobileGL::MG_Impl::GLImpl { // every setter reaches" - and MGPTextureParams takes MinLod, MaxLod and LodBias off that // object, so every glTexParameter that writes GL_TEXTURE_MIN_LOD / MAX_LOD / LOD_BIAS // landed on state nothing watched and the applier's record kept saying MinLod = 0. - // Wrong pixels, not a lost optimisation. + // Wrong pixels, not a lost optimization. // // THE HOOK IS HERE RATHER THAN ON BumpVersion because MG_State/GLState/SamplerState is // package C's after the tag; C.7 grants this file for exactly this class of path ("the @@ -2700,9 +2700,9 @@ namespace MobileGL::MG_Impl::GLImpl { return MG_State::pGLContext->ValidateTextureObject(texture) ? GL_TRUE : GL_FALSE; } - // Every texture parameter but the border colour, for one resolved texture: up to four values, + // Every texture parameter but the border color, for one resolved texture: up to four values, // as doubles because a double holds each enum, level and float this state stores exactly. False - // after recording an error. The border colour converts differently for each query type (GL 4.6 + // after recording an error. The border color converts differently for each query type (GL 4.6 // core 8.11.2), so each form answers it itself. static Bool QueryTextureParameter(const SharedPtr& textureObject, GLenum pname, Double (&values)[4], Uint& count, const char* caller) { @@ -2819,7 +2819,7 @@ namespace MobileGL::MG_Impl::GLImpl { GLenum pname, GLint* params, const char* caller) { if (pname == GL_TEXTURE_BORDER_COLOR) { // The inverse of glTexParameteriv: GL 4.6 core equation 2.3 against equation 2.2 on the - // write side (SetTextureBorderColorFromInts). The raw integer colour is the Iiv query's. + // write side (SetTextureBorderColorFromInts). The raw integer color is the Iiv query's. const auto& borderColor = textureObject->GetBorderColor(); for (int i = 0; i < 4; ++i) params[i] = MG_Util::FloatToSignedNormalizedInt32(borderColor[i]); @@ -3302,7 +3302,7 @@ namespace MobileGL::MG_Impl::GLImpl { namespace { // The eleven targets GL 4.6 core 18.3.2 accepts. GL_TEXTURE_BUFFER, the six cube FACE - // enums and every PROXY enum all convert to a TextureTarget this frontend recognises, + // enums and every PROXY enum all convert to a TextureTarget this frontend recognizes, // so ValidateTextureTarget lets them through; here they are INVALID_ENUM. Bool ValidateCopyImageTarget(GLenum target, const char* endpointName) { switch (target) { @@ -3786,7 +3786,7 @@ namespace MobileGL::MG_Impl::GLImpl { const Int z = cubeFaces ? 0 : offset.z(); const Int depth = cubeFaces ? 1 : size.z(); // Subtractions rather than sums: offset + extent are application-supplied GLints, and a - // signed overflow is undefined behaviour a compiler may resolve by assuming the check passes. + // signed overflow is undefined behavior a compiler may resolve by assuming the check passes. if (offset.x() < 0 || offset.y() < 0 || z < 0 || size.x() > levelSize.x() - offset.x() || size.y() > levelSize.y() - offset.y() || depth > levelDepth - z) { MG_State::pGLContext->RecordError( @@ -4421,7 +4421,7 @@ namespace MobileGL::MG_Impl::GLImpl { // // ProcessTexturePixelsDataPack performs NO format or type conversion: it sizes every texel with // GetInternalBytesPerPixel(the TEXTURE's internal format) and memcpys the shadow rows verbatim, - // and it carries a standing TODO for the pixel-store parameters, so it honours only SwapBytes and + // and it carries a standing TODO for the pixel-store parameters, so it honors only SwapBytes and // the bitmap LSBFirst path. Both facts are invisible from the outside, and both are dangerous: // // * a (format, type) narrower than the shadow's own texel makes the copy write MORE bytes than @@ -4432,7 +4432,7 @@ namespace MobileGL::MG_Impl::GLImpl { // overflow but is still wrong data. // * a pack state that puts padding, a row-length override or a skip offset between rows is // ignored outright, so the rows land at the wrong destination strides - while the GPU - // readback path (DirectGLES StoreClientRows, and DirectVulkan through it) honours all of it. + // readback path (DirectGLES StoreClientRows, and DirectVulkan through it) honors all of it. // Same glGetTexImage call, two different destination layouts, decided by whether the texture // happens to have a GPU image. // @@ -4475,7 +4475,7 @@ namespace MobileGL::MG_Impl::GLImpl { ErrorCode::InvalidOperation, MakeUnique( "MG_Impl/GLImpl", caller, - "The CPU-shadow readback path packs rows tightly and cannot honour a pixel-store state that " + "The CPU-shadow readback path packs rows tightly and cannot honor a pixel-store state that " "adds row padding, a row-length override or a skip offset.")); return false; } @@ -6100,7 +6100,7 @@ namespace MobileGL::MG_Impl::GLImpl { // The backend publishes where its device really places the samples of each count (a // shader's gl_SamplePosition reads the same places). A count it could not determine keeps - // answering the pixel centre. + // answering the pixel center. Float position[2] = {0.5f, 0.5f}; if (MG_Backend::pActiveBackendObject != nullptr) { MG_Backend::pActiveBackendObject->GetDynamicParameters().GetSamplePosition(samples, static_cast(index), diff --git a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h index f3af9361..e1840059 100644 --- a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h +++ b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.h @@ -19,7 +19,7 @@ namespace MobileGL::MG_Impl::GLImpl { // // It answers a NARROWER contract than glGetTexImage's, and refuses what it cannot do rather than // answering wrongly. The copy is verbatim: it performs no format or type conversion, and it packs - // rows tightly, honouring only GL_PACK_SWAP_BYTES and the bitmap GL_PACK_LSB_FIRST path. A + // rows tightly, honoring only GL_PACK_SWAP_BYTES and the bitmap GL_PACK_LSB_FIRST path. A // request whose (format, type) texel size differs from the texture's own, or a pixel-store state // that adds row padding / a row-length override / a skip offset, is rejected with // GL_INVALID_OPERATION (see ValidateShadowReadbackLayout, which spells out why each is unsafe). diff --git a/MobileGL/MG_Impl/GLImpl/Texture/Validators.cpp b/MobileGL/MG_Impl/GLImpl/Texture/Validators.cpp index 0ebe0479..0b57cc0d 100644 --- a/MobileGL/MG_Impl/GLImpl/Texture/Validators.cpp +++ b/MobileGL/MG_Impl/GLImpl/Texture/Validators.cpp @@ -249,7 +249,7 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl { case TextureInternalFormat::Depth24Stencil8: case TextureInternalFormat::Depth32FStencil8: case TextureInternalFormat::DepthStencil: - // Stencil-only is not a colour format either: a colour client format read against a + // Stencil-only is not a color format either: a color client format read against a // STENCIL_INDEX8 texture has to be the same INVALID_OPERATION as against a depth one. case TextureInternalFormat::StencilIndex8: return true; @@ -336,7 +336,7 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl { } // The stencil-only transfer path arrived with GL 4.4 / ARB_texture_stencil8, and only ever - // pairs with stencil-only storage: against a depth, depth-stencil or colour internal format + // pairs with stencil-only storage: against a depth, depth-stencil or color internal format // STENCIL_INDEX keeps the pre-4.4 answer (GL CTS packed_pixels feeds exactly that pairing // and expects INVALID_OPERATION). if (format == TextureInputFormat::StencilIndex && internalFormat != TextureInternalFormat::StencilIndex8) { @@ -506,9 +506,9 @@ namespace MobileGL::MG_Impl::GLImpl::TextureImpl { namespace { // Component set of an UNSIZED base internal format, as the bitmask GL 4.6 SS 8.6 - // reasons about. Colour components are independent bits so "subset" is a plain + // reasons about. Color components are independent bits so "subset" is a plain // mask test; depth and stencil are their own components and never satisfy a - // colour request (or each other). + // color request (or each other). enum : Uint32 { kComponentR = 1u << 0, kComponentG = 1u << 1, diff --git a/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp b/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp index 9e340124..d206e0c2 100644 --- a/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp +++ b/MobileGL/MG_Impl/GLImpl/VertexArray/Validators.cpp @@ -106,7 +106,7 @@ namespace MobileGL::MG_Impl::GLImpl::VertexArrayImpl { Int stride, Bool integerPath) { constexpr const char* fn = "ValidateVertexAttribFormat"; // GL_UNSIGNED_INT_10F_11F_11F_REV is a three-component float-path-only packing that has no - // DataType of its own, so it has to be recognised by name before the conversion below turns + // DataType of its own, so it has to be recognized by name before the conversion below turns // it into Unknown and reports the wrong error (GL 4.6 core 10.3.2). if (glType == GL_UNSIGNED_INT_10F_11F_11F_REV) { if (integerPath) { diff --git a/MobileGL/MG_Impl/GLXImpl/GLXImpl.cpp b/MobileGL/MG_Impl/GLXImpl/GLXImpl.cpp index 0de88cfa..6684389e 100644 --- a/MobileGL/MG_Impl/GLXImpl/GLXImpl.cpp +++ b/MobileGL/MG_Impl/GLXImpl/GLXImpl.cpp @@ -329,7 +329,7 @@ namespace MobileGL::MG_Impl::GLXImpl { }; thread_local ThreadCurrent t_current; - // vblank_mode=0 (the benchmark convention X11 GL drivers honour) never waits for the + // vblank_mode=0 (the benchmark convention X11 GL drivers honor) never waits for the // display, whatever the application asks; anything else leaves the interval to it. Bool VblankForcedOff() { static const Bool off = [] { diff --git a/MobileGL/MG_Impl/GLXImpl/X11PresentXcb.h b/MobileGL/MG_Impl/GLXImpl/X11PresentXcb.h index db1b322a..00a5a42d 100644 --- a/MobileGL/MG_Impl/GLXImpl/X11PresentXcb.h +++ b/MobileGL/MG_Impl/GLXImpl/X11PresentXcb.h @@ -34,7 +34,7 @@ namespace MobileGL::MG_Impl::GLXImpl::X11Present { // THE MIT-SHM FALLBACK: frames read back into a shared segment (a memfd passed with // ShmAttachFd, so no SysV memory has to be shared with the X server) and put with ShmPutImage - - // the pixels reach the X server without travelling down its socket. Two segments, alternating; + // the pixels reach the X server without traveling down its socket. Two segments, alternating; // a segment is written again only after a round trip queued behind its last put has come back. class ShmPresenter { public: diff --git a/MobileGL/MG_Impl/Pipe/CsoCache.h b/MobileGL/MG_Impl/Pipe/CsoCache.h index e7fb8817..6337a33c 100644 --- a/MobileGL/MG_Impl/Pipe/CsoCache.h +++ b/MobileGL/MG_Impl/Pipe/CsoCache.h @@ -129,7 +129,7 @@ namespace MobileGL::MG_Pipe { desc.BaseCso = kMGPipeNullHandle; // A brand-new CSO names every pipeline chunk; the incremental form against a // BaseCso is what the applier's assertion allows and P3 will use once a CSO is - // minted from a neighbour rather than from nothing. + // minted from a neighbor rather than from nothing. desc.ChunkMask = kAllPipelineChunks; desc.Blob.Size = kMGPipePipelineChunkBytes; MGPipeRouteCreateRenderState(desc, bytes.data()); diff --git a/MobileGL/MG_Impl/Pipe/FramebufferEmit.h b/MobileGL/MG_Impl/Pipe/FramebufferEmit.h index d583a416..9f5edc95 100644 --- a/MobileGL/MG_Impl/Pipe/FramebufferEmit.h +++ b/MobileGL/MG_Impl/Pipe/FramebufferEmit.h @@ -86,7 +86,7 @@ namespace MobileGL::MG_Pipe { // `res` is handed in because resolving it needs the slot allocator and this function stays // pure; `internalFormat` is INLINE in the record on purpose, so the four cross-object masks // fall out at push time with no lookup on the far side. - // THE EMPTY POINT IS THE ZERO-INITIALISED RECORD EXCEPT FOR ITS TWO TARGET FIELDS. Both + // THE EMPTY POINT IS THE ZERO-INITIALIZED RECORD EXCEPT FOR ITS TWO TARGET FIELDS. Both // are Uint16 enumerations whose zero is a REAL value - TextureTarget::Texture1D and // TextureUploadTarget::Texture1D - so a reader that forgot to gate on Kind would read a // plausible wrong answer rather than a nonsense one. Unknown (0xFFFF) is what the contract @@ -134,7 +134,7 @@ namespace MobileGL::MG_Pipe { // -1 for NONE, which is the field's documented convention read literally. // // THE FOUR DEFAULT-FRAMEBUFFER TOKENS map to 0, and that is a deliberate narrowing rather - // than an oversight: a default framebuffer has one colour surface, this record carries it + // than an oversight: a default framebuffer has one color surface, this record carries it // in Color[0] (see MGPipeBuildFramebufferState), and IsDefault is what tells the server // which framebuffer it is looking at. The distinction the narrowing loses is FRONT versus // BACK and LEFT versus RIGHT, which MobileGL's frontend never gives a default framebuffer @@ -149,7 +149,7 @@ namespace MobileGL::MG_Pipe { return 0; } - // m2: A DRAW-BUFFER TOKEN CAN NAME A COLOUR POINT THE RECORD CANNOT CARRY, and D-C3's + // m2: A DRAW-BUFFER TOKEN CAN NAME A COLOR POINT THE RECORD CANNOT CARRY, and D-C3's // refusal loop only ever scanned ATTACHMENTS. `glDrawBuffers(1, {GL_COLOR_ATTACHMENT10})` // with nothing attached at 10 is legal state - draw-incomplete, but legal - and the index // above would have written 10 into a record whose Color[] is 8 wide, so the server would @@ -240,7 +240,7 @@ namespace MobileGL::MG_Pipe { if (!drawFbo && !readFbo) return 0; // ONE OBJECT BOUND TO BOTH TARGETS IS ONE RECORD WITH Target = Both, and that is - // not an optimisation: Espryt's "same FBO as draw" skip is the habitat of the + // not an optimization: Espryt's "same FBO as draw" skip is the habitat of the // read-buffer defect class, and a record that says which target it describes turns // "apply the draw buffers only for the draw target" from call-site discipline into // a one-line test on the far side. @@ -458,7 +458,7 @@ namespace MobileGL::MG_Pipe { static_cast(FramebufferAttachmentType::Color0) + static_cast(kMGPipeMaxColorAttachments); point <= static_cast(FramebufferAttachmentType::ColorMax); ++point) { if (fbo.GetAttachment(static_cast(point)).IsEmpty()) continue; - MGLOG_E_ONCE("MGPipe: framebuffer %u has an attachment at colour point %d, which is at or " + MGLOG_E_ONCE("MGPipe: framebuffer %u has an attachment at color point %d, which is at or " "above the wire width of %u - set_framebuffer_state is refused rather than " "truncated and the legacy arm runs", fbo.GetExternalIndex(), point - static_cast(FramebufferAttachmentType::Color0), @@ -467,14 +467,14 @@ namespace MobileGL::MG_Pipe { return false; } - // m2, THE SAME REFUSAL ONE FIELD OVER. A draw-buffer token may name a colour point + // m2, THE SAME REFUSAL ONE FIELD OVER. A draw-buffer token may name a color point // at or above the wire width with nothing attached there, which the loop above // cannot see; MGPipeDrawBufferIndex would then write 8..31 into an 8-wide array. { const auto& tokens = fbo.GetDrawBuffers(); for (SizeT i = 0; i < kMGPipeMaxColorAttachments; ++i) { if (MGPipeDrawBufferIsInsideTheWireWidth(tokens[i])) continue; - MGLOG_E_ONCE("MGPipe: framebuffer %u names colour point %d in draw buffer %u, which is " + MGLOG_E_ONCE("MGPipe: framebuffer %u names color point %d in draw buffer %u, which is " "at or above the wire width of %u - set_framebuffer_state is refused " "rather than truncated and the legacy arm runs", fbo.GetExternalIndex(), @@ -591,7 +591,7 @@ namespace MobileGL::MG_Pipe { MGPipeTextureEmitter& textures = MGPipeTextureEmitterInstance(); // D-A4's two producers: an attachment point is what sets RENDER_TARGET and // DEPTH_STENCIL, the two sticky bind bits nothing set before P4a. Sticky and ORed, - // so a texture that was ever a colour attachment keeps saying so, and the mask is + // so a texture that was ever a color attachment keeps saying so, and the mask is // republished on the resource's next respecify. const Uint16 bit = (type == FramebufferAttachmentType::Depth || type == FramebufferAttachmentType::Stencil) ? static_cast(kMGPipeBindDepthStencil) diff --git a/MobileGL/MG_Impl/Pipe/ImageEmit.h b/MobileGL/MG_Impl/Pipe/ImageEmit.h index 45dd0dd6..cd7c4b69 100644 --- a/MobileGL/MG_Impl/Pipe/ImageEmit.h +++ b/MobileGL/MG_Impl/Pipe/ImageEmit.h @@ -10,7 +10,7 @@ #include // Client side of set_shader_images, under SamplerEmit.h's subsystem bit (one family, one A/B). -// Two invariants an optimisation must keep. An image window of 0 emits nothing before any hash, +// Two invariants an optimization must keep. An image window of 0 emits nothing before any hash, // so a draw that uses no images pays one integer test. The shutter gating the sweep mixes only // frontend counters (texture content and params, program image units, texture binds), never a // backend re-mint counter: a texture bound only to an image unit is re-minted inside the sweep, diff --git a/MobileGL/MG_Impl/Pipe/PipeFill.cpp b/MobileGL/MG_Impl/Pipe/PipeFill.cpp index aba11f02..fa97dda8 100644 --- a/MobileGL/MG_Impl/Pipe/PipeFill.cpp +++ b/MobileGL/MG_Impl/Pipe/PipeFill.cpp @@ -910,7 +910,7 @@ namespace MobileGL::MG_Pipe { const void* initialBytes = (carryBase && buffer.GetSize() > 0) ? buffer.MappedData() : nullptr; // kNeedsAck rides on the CALL and MGPipeResourceRespecifyNeedsAck(desc) decides per // record: only an immutable store (a glBufferStorage*) is a real synchronous - // allocation and only it is allowed one. In monolith the acknowledgement is + // allocation and only it is allowed one. In monolith the acknowledgment is // ((void)0), because the applier is one function call away and has already run by // the time this returns; the transport wires the doorbell to that same predicate. #if MOBILEGL_BUILD_DISAGGREGATED @@ -1061,7 +1061,7 @@ namespace MobileGL::MG_Pipe { record.Res = handle; record.Offset = offset; record.Size = size; - // The application's REAL flags, not a normalised subset: the backend's kill-switch + // The application's REAL flags, not a normalized subset: the backend's kill-switch // arm reads INVALIDATE_RANGE / INVALIDATE_BUFFER / UNSYNCHRONIZED per call to choose // between a map+memcpy+unmap and an upload, so merging them here would change which. record.AccessFlags = accessFlags; @@ -1103,8 +1103,8 @@ namespace MobileGL::MG_Pipe { MGPipeRouteResourceReadback(record); } - // NO UnmapPersistent PRODUCER IN P3a, AND THAT IS DELIBERATE. The catalogue has the call - // and wire implemented it, but D-J forbids new behaviour and there is nothing to convert: + // NO UnmapPersistent PRODUCER IN P3a, AND THAT IS DELIBERATE. The catalog has the call + // and wire implemented it, but D-J forbids new behavior and there is nothing to convert: // BufferBackendOps has seven hooks and none of them is an unmap, and // PipeResource::ReleasePersistentMap() (BufferObject.cpp, from RedefineStorage) tells the // backend nothing today - it learns from the Respecify that follows. Emitting @@ -1913,7 +1913,7 @@ namespace MobileGL::MG_Pipe { // PipeInputs.h's F-class block, so freshness never reaches them and the exit gate was // structurally blind on exactly the seven most dangerous rows. The hook is a no-op outside // a server-stamped verb, so InvalidateCompileEnv keeps being reachable from backend - // initialisation - the case the exemption was written for - and every monolith lane, split + // initialization - the case the exemption was written for - and every monolith lane, split // build included, behaves as it does today. #if MOBILEGL_BUILD_DISAGGREGATED #define MGP_STICKY_FORWARD_PULL(Field) MGPipeStickyForwardPull(MGPipeInputField::Field) @@ -1958,7 +1958,7 @@ namespace MobileGL::MG_Pipe { namespace { // The frontend half of MGPipeNotifyCompileEnvChanged (PipeApply.h): registered once, at - // static initialisation, by the translation unit that owns the forward. + // static initialization, by the translation unit that owns the forward. const Bool kCompileEnvHookRegistered = [] { MGPipeSetCompileEnvChangedHook([] { if (gPipeInputs->IsLive()) gPipeInputs->InvalidateCompileEnv(); @@ -2512,7 +2512,7 @@ namespace MobileGL::MG_Pipe { MGPipeFieldMask SuppliedFieldMask(Uint64 pushMask, Bool applierDerives, Bool contextValuesWireLive) { // THE CONSUMER SIGNAL IS READ ONLY WHERE THE WALK BELOW COULD REACH IT, and that - // guard is not a micro-optimisation - it is what keeps R-8's DIAGNOSTIC COUNTERS + // guard is not a micro-optimization - it is what keeps R-8's DIAGNOSTIC COUNTERS // where they were (P5d r3 package C review, minor 2). In the conjunction below // P4aFamilyHasItsConsumer sits AFTER `(pushMask & subsystem) != 0`, and it answers a // constant `true` for every subsystem outside the P4a families - so at a mask that @@ -2664,7 +2664,7 @@ namespace MobileGL::MG_Pipe { // default: MGPipeApplierReset() clears the CSO store and the residual block and // leaves gPipeInputs->m_currentVertexAttribute holding the PREVIOUS context's // defaults. So the InvalidateAll() a fresh context does to the set-hash - // suppressor would have been cancelled two lines later by this diff, and the one + // suppressor would have been canceled two lines later by this diff, and the one // call P2 fully owns would publish nothing across a context change - exactly the // "memo that serves a stale answer" the tracker's own COMPLETE-state rule // (Tracker.h) exists to forbid. EmitRenderState has the same arm @@ -2724,7 +2724,7 @@ namespace MobileGL::MG_Pipe { // counters, the 15 per-target touched-buffer-binding counts and the five XFB values - // emitted at validate WHEN ANY COVERED VALUE MOVED, which the whole-record hash says: // there is deliberately no dirty bit for the family (the tracker's value-class dirty - // accounting is untouched - "零新增记账", ARCHITECTURE.md 5.2) and no dirty mask in the + // accounting is untouched - "no new accounting", ARCHITECTURE.md 5.2) and no dirty mask in the // payload, so a suppressed record means "nothing moved", never "field invalid" (§1). // // THE PRODUCER IS TRANSPORT-GATED, and the residual-fill skip for the same eight fields @@ -2906,7 +2906,7 @@ namespace MobileGL::MG_Pipe { // // THE ORDER IS ARCHITECTURE.md 5.4's RECOMMENDED ONE - framebuffer, then program, then // textures/sampler/image/global constants - and that document is explicit that the - // order is code organisation and NOT a contract: all of a verb's set_*/bind_* must + // order is code organization and NOT a contract: all of a verb's set_*/bind_* must // complete before the verb, and apart from "a resource create precedes a bind to it" // there is no ordering requirement between them. The server specialises the shader and // the pipeline lazily at the verb, from everything it holds at that moment, which is @@ -2951,7 +2951,7 @@ namespace MobileGL::MG_Pipe { // points and bit 16 is the two writable classes, which share a shutter because a // storage bind and a counter bind are the same event to every reader of the record. // Bit 17's family (set_stream_output_targets) has no adapter at all - XFB stays - // lockstep for the whole of P5e (§5.7) - and that absence is the catalogue's split, + // lockstep for the whole of P5e (§5.7) - and that absence is the catalog's split, // not an omission. Uint64 EmitConstBuffers(GLContext& ctx) { return MGPipeShaderBufferEmitterInstance().EmitConstBuffers(ctx); @@ -3005,7 +3005,7 @@ namespace MobileGL::MG_Pipe { // an unbarriered verb is allowed to hand the server. // // `fillOwed` is deliberately a separate name from `barriered`, and that is what makes - // the red-once one line: setting it to `true` restores the old behaviour (a fill for + // the red-once one line: setting it to `true` restores the old behavior (a fill for // every verb) and the guard below then fires Fatal{RoleViolation, "gPipeInputs"} on // the first unbarriered verb, by name. const Bool runAhead = ClientRunsAhead(); @@ -3033,7 +3033,7 @@ namespace MobileGL::MG_Pipe { // §2.1's predicate, client-side (see ClientVerbIsBarriered). const Bool barriered = !runAhead || ClientVerbIsBarriered(verb, ctx); // THE ONE LINE THE RED-ONCE FLIPS: `= true` here is "fill for every verb", the - // pre-P5e behaviour, and it turns the guard below into the abort §3.5 names. + // pre-P5e behavior, and it turns the guard below into the abort §3.5 names. const Bool fillOwed = barriered; g_lastFillWasBarriered = fillOwed; if (fillOwed) { @@ -3197,7 +3197,7 @@ namespace MobileGL::MG_Pipe { // P4a's segment, in ARCHITECTURE.md 5.4's RECOMMENDED order - framebuffer, then // program, then textures / sampler / image / global constants - which is why it stands // before the render-state block rather than after it. That order is explicitly code - // organisation and not a contract (all of a verb's set_*/bind_* complete before the + // organization and not a contract (all of a verb's set_*/bind_* complete before the // verb, and the server specialises lazily AT the verb from everything it then holds), // so nothing about the P2 and P3a emissions changes by standing after it; what it buys // is that the file reads in the order the design states. @@ -3241,7 +3241,7 @@ namespace MobileGL::MG_Pipe { } // P5e's segment (sb, §5.6): the indexed buffer binding points, AFTER the program - // segment for the same "code organisation, not a contract" reason ARCHITECTURE.md 5.4 + // segment for the same "code organization, not a contract" reason ARCHITECTURE.md 5.4 // gives for P4a's order - all of a verb's set_*/bind_* complete before the verb, and // the server resolves a point against its own descriptor at its sync point. It reads // better here because the uniform window is what the program's block bindings INDEX diff --git a/MobileGL/MG_Impl/Pipe/ProgramEmit.h b/MobileGL/MG_Impl/Pipe/ProgramEmit.h index 68f91c20..5013da6c 100644 --- a/MobileGL/MG_Impl/Pipe/ProgramEmit.h +++ b/MobileGL/MG_Impl/Pipe/ProgramEmit.h @@ -395,7 +395,7 @@ namespace MobileGL::MG_Pipe { m_lastDesc.ReservedNumSamplesOffset = static_cast(spirv.reservedNumSamplesOffset); m_lastDesc.SpirvStatus = spirv.spirvStatus ? 1 : 0; // P5e (pg), ID-88 / ruling 9: THE FAILED RELINK OF A BOUND PROGRAM, and the ruling - // asked this package to verify the frontend's actual behaviour rather than assume + // asked this package to verify the frontend's actual behavior rather than assume // it. VERIFIED, at ProgramObject.cpp:510-531: `Link()`'s PROLOGUE bumps // m_linkVersion and then assigns `m_artifacts = {}` - "the complete not-linked // state" in its own words - before the link body runs, and every failure arm of diff --git a/MobileGL/MG_Impl/Pipe/ResourceTracker.h b/MobileGL/MG_Impl/Pipe/ResourceTracker.h index 53136652..e403ea09 100644 --- a/MobileGL/MG_Impl/Pipe/ResourceTracker.h +++ b/MobileGL/MG_Impl/Pipe/ResourceTracker.h @@ -571,7 +571,7 @@ namespace MobileGL::MG_Pipe { // A draw or dispatch wrote these ranges. ARCHITECTURE.md 7.1 calls this a NARROWING // channel - the client builds a conservative pending set at its own emission points and // the callback only ever removes from it - so P3a's implementation marks exactly what - // the three Espryt MarkGpuWritten sites mark today and the observable behaviour is + // the three Espryt MarkGpuWritten sites mark today and the observable behavior is // unchanged. The narrowing itself is P8/P9's. inline void MGPipeClientOnGpuWritten(MGPipeHandle res, Uint rangeCount, const MGPRange* ranges) { // THE SHAPE IS A CONTRACT POINT, not a formality: the announcement is ONE range diff --git a/MobileGL/MG_Impl/Pipe/SamplerEmit.h b/MobileGL/MG_Impl/Pipe/SamplerEmit.h index 338be842..e6ef9d94 100644 --- a/MobileGL/MG_Impl/Pipe/SamplerEmit.h +++ b/MobileGL/MG_Impl/Pipe/SamplerEmit.h @@ -74,7 +74,7 @@ namespace MobileGL::MG_Pipe { canon.borderColor = src.borderColor; canon.borderColorI = src.borderColorI; canon.borderColorUI = src.borderColorUI; - // ALL FOUR BORDER-COLOUR MEMBERS CROSS, the form included. All three representations + // ALL FOUR BORDER-COLOR MEMBERS CROSS, the form included. All three representations // are always numerically populated, so the value alone cannot say which driver entry // point applies (glSamplerParameterIiv vs fv, or which VkBorderColor family), and both // of Espryt's redundancy filters compare all four. Dropping this one line is G7's @@ -662,7 +662,7 @@ namespace MobileGL::MG_Pipe { // XXH64 over the tail entries, with Start and Count mixed in through MGPipeMixShutter - // the VertexInputEmit shape, and for its reason: the hash must cover EVERY input the // record carries, or a record whose one changed field is outside the tail gets suppressed. - // Both tails are built into zero-initialised staging arrays, so no padding byte enters + // Both tails are built into zero-initialized staging arrays, so no padding byte enters // either hash. inline Uint64 MGPipeSamplerViewSetContentHash(const MGPBoundView* entries, Uint32 start, Uint32 count) { Uint64 hash = XXH64(entries, static_cast(count) * sizeof(MGPBoundView), 0); diff --git a/MobileGL/MG_Impl/Pipe/SlotAllocator.h b/MobileGL/MG_Impl/Pipe/SlotAllocator.h index ca9c0f48..0a4fcd15 100644 --- a/MobileGL/MG_Impl/Pipe/SlotAllocator.h +++ b/MobileGL/MG_Impl/Pipe/SlotAllocator.h @@ -109,7 +109,7 @@ namespace MobileGL::MG_Pipe { Vector FreeList; // P4a: the ShaderCso COMPOSITE band, indexed by (slot - the band's base) and // EMPTY for every other kind. A SECOND VECTOR RATHER THAN MORE OF THE FIRST, and - // it is not a micro-optimisation: the band starts at 983040, so minting one + // it is not a micro-optimization: the band starts at 983040, so minting one // composite into the slot-indexed vector above would allocate ~983k SlotStates - // ~23 MB - for a single program pipeline, and a consumer that sized a table off // HighWater would pay the same shape again with a far bigger record. Both spaces diff --git a/MobileGL/MG_Impl/Pipe/TextureEmit.h b/MobileGL/MG_Impl/Pipe/TextureEmit.h index dec00b3f..287d84b7 100644 --- a/MobileGL/MG_Impl/Pipe/TextureEmit.h +++ b/MobileGL/MG_Impl/Pipe/TextureEmit.h @@ -93,7 +93,7 @@ namespace MobileGL::MG_Pipe { // THE TARGET IS THE ONLY LEGAL SOURCE AT THE ONE MOMENT THIS MATTERS: resource_create is // emitted from TextureObjectBase's constructor (D-D1), where the derived object does not // exist yet and GetStorageType() is a PURE virtual - calling it there is undefined - // behaviour, not merely a wrong answer. The mapping is exact and total: TextureObjectBuffer + // behavior, not merely a wrong answer. The mapping is exact and total: TextureObjectBuffer // is the only class that reports Buffer and TextureTarget::TextureBuffer is the only target // it is ever constructed with, which MGPipeTextureStorageKindAgreesWithObject below // re-checks at the first respecify, where the object IS complete. @@ -194,7 +194,7 @@ namespace MobileGL::MG_Pipe { desc.Samples = static_cast(std::max(texture.GetSamples(), 0)); desc.FixedSampleLocations = texture.HasFixedSampleLocations() ? 1 : 0; // A real descriptor fact the backend reads (glTexStorage* / a texture view), and - // it must NOT be read as "this respecify wants an acknowledgement": + // it must NOT be read as "this respecify wants an acknowledgment": // MGPipeResourceRespecifyNeedsAck is narrowed to name the buffer target, because // texture allocation is lazy in monolith and stays lazy in split. desc.Immutable = texture.IsImmutable() ? 1 : 0; @@ -665,7 +665,7 @@ namespace MobileGL::MG_Pipe { // GetTarget(), GetExternalIndex() and GetLifetimeId() are all overridden ON THE BASE, // so they dispatch to the base's own bodies here and read members the mem-init list has // already written; GetStorageType() and GetUploadTargets() are NOT, so calling either - // would be undefined behaviour and the storage kind is derived from the target instead + // would be undefined behavior and the storage kind is derived from the target instead // (exact, and re-checked at the first respecify where the object IS complete). void EmitResourceCreate(ITextureObject& texture) { const MGPipeHandle handle = AcquireTexture(texture.GetLifetimeId(), &texture); diff --git a/MobileGL/MG_Impl/Pipe/Tracker.h b/MobileGL/MG_Impl/Pipe/Tracker.h index 1ed1fb3e..885eb498 100644 --- a/MobileGL/MG_Impl/Pipe/Tracker.h +++ b/MobileGL/MG_Impl/Pipe/Tracker.h @@ -189,7 +189,7 @@ namespace MobileGL::MG_Pipe { // can collide and miss a fire; over lifetime ids, versions and generations an application // cannot steer, that is about 2^-64 per pair, accepted instead of comparing the whole state // on every verb. The mix must avalanche: a hash_combine-style step collides outright on small - // neighbouring counters ((1, 64) and (2, 1)), and a missed bit-12 fire then leaves a draw + // neighboring counters ((1, 64) and (2, 1)), and a missed bit-12 fire then leaves a draw // sampling the previous texture set. Each step is a bijection in either argument with the // other fixed, so a change to one input alone always changes the result. inline constexpr Uint64 MGPipeShutterAvalanche(Uint64 value) { @@ -521,7 +521,7 @@ namespace MobileGL::MG_Pipe { // fired none of the four and A recorded the stale framebuffer, view and sampler sets. // The group keeps a twin of each aggregate, and each bit fires here on exactly the // twins of what its own shutter reads above. An exact compare rather than one more - // MGPipeMixShutter for vaoChanged's reason: the four are small neighbouring counters. + // MGPipeMixShutter for vaoChanged's reason: the four are small neighboring counters. // A single-context group skips the clocks behind one relaxed load; the first walk // after a second context joins may fire the four once, which is the safe direction. // The program bits need nothing of this: a program is a group object too, but its diff --git a/MobileGL/MG_Impl/Pipe/Verb/TextureReadbackEmit.inc b/MobileGL/MG_Impl/Pipe/Verb/TextureReadbackEmit.inc index ee677944..7e6c8119 100644 --- a/MobileGL/MG_Impl/Pipe/Verb/TextureReadbackEmit.inc +++ b/MobileGL/MG_Impl/Pipe/Verb/TextureReadbackEmit.inc @@ -55,7 +55,7 @@ // Returns the pack buffer's handle when a read into it may skip the reply: the read // then crosses as read_pixels_to_buffer / get_texture_image_to_buffer, lands // server-side, and the buffer is marked GPU-written. Returns null, selecting the - // reply-slot form, when that mark could not be honoured: MOBILEGL_IPC_PBO_READBACK_SYNC=1; + // reply-slot form, when that mark could not be honored: MOBILEGL_IPC_PBO_READBACK_SYNC=1; // no readback route (BufferWritebackIsReachable); a mapped buffer, whose persistent // reader never goes through SyncGpuWrites; an `end` (last byte past the application // offset) above MGPSubData's 2^31-1 offset limit; or a buffer with no handle yet. diff --git a/MobileGL/MG_Impl/Pipe/Verb/VerbPort.cpp b/MobileGL/MG_Impl/Pipe/Verb/VerbPort.cpp index 4033ca2d..6f83de45 100644 --- a/MobileGL/MG_Impl/Pipe/Verb/VerbPort.cpp +++ b/MobileGL/MG_Impl/Pipe/Verb/VerbPort.cpp @@ -1706,7 +1706,7 @@ namespace MobileGL::MG_Record { const Uint64 rowPixels = pack.RowLength > 0 ? static_cast(pack.RowLength) : static_cast(width); const Uint64 alignment = pack.Alignment > 0 ? static_cast(pack.Alignment) : 1ull; const Uint64 strideBytes = ((rowPixels * bytesPerPixel + alignment - 1) / alignment) * alignment; - // m6: the client re-derives GL 4.6 8.4.4's pack layout, so it honours GL_PACK_ROW_LENGTH + // m6: the client re-derives GL 4.6 8.4.4's pack layout, so it honors GL_PACK_ROW_LENGTH // VERBATIM - including the ill-formed 0 < ROW_LENGTH < width, where the row stride is // narrower than a written row and consecutive rows overlap. GL leaves that case to the // implementation; the client reproduces exactly what the monolith backend's own scatter @@ -1835,7 +1835,7 @@ namespace MobileGL::MG_Record { // makes it an offset, never an address - the emitter refused the other case by name). block.Offset = static_cast(reinterpret_cast(indirect)); block.ParameterOffset = hasParameterBuffer ? static_cast(parameterOffset) : 0u; - // 0 = tightly packed, as GL spells it; the backend normalises. Negative counts and + // 0 = tightly packed, as GL spells it; the backend normalizes. Negative counts and // strides have already been refused by the frontend. block.Stride = stride > 0 ? static_cast(stride) : 0u; block.DrawCount = drawCount > 0 ? static_cast(drawCount) : 0u; diff --git a/MobileGL/MG_Impl/Pipe/VertexInputEmit.h b/MobileGL/MG_Impl/Pipe/VertexInputEmit.h index 736093c0..c63ada98 100644 --- a/MobileGL/MG_Impl/Pipe/VertexInputEmit.h +++ b/MobileGL/MG_Impl/Pipe/VertexInputEmit.h @@ -451,7 +451,7 @@ namespace MobileGL::MG_Pipe { private: // P14: what EmitVertexElements / EmitVertexBuffers / EmitIndexBuffer resolve from a VAO, // one entry per live VAO keyed on its lifetime id (monotonic, never reused), erased at the - // VAO's death and re-initialised after an allocator reset. A direct-mapped table was tried + // VAO's death and re-initialized after an allocator reset. A direct-mapped table was tried // first and lost most entries to collisions: a Minecraft frame draws ~1,500 chunk arrays // whose ids spread well past any fixed table. The handles and entries it keeps change no // record; the kept-binding mirror below does decide what is sent, and is only ever diff --git a/MobileGL/MG_Impl/SharedImageApi.h b/MobileGL/MG_Impl/SharedImageApi.h index 58683afd..423176ed 100644 --- a/MobileGL/MG_Impl/SharedImageApi.h +++ b/MobileGL/MG_Impl/SharedImageApi.h @@ -13,7 +13,7 @@ * name one it was handed, through the process's own MobileGL client session. The component * resolves them with dlsym; nothing links against them. * - * Images are server-allocated colour buffers exported as dma-buf descriptors. Their memory layout + * Images are server-allocated color buffers exported as dma-buf descriptors. Their memory layout * is the allocator's: the modifier reported is DRM_FORMAT_MOD_INVALID, and the only meaningful * thing to do with a descriptor is to hand it back (an import, here or through EGL) - not to map * it and assume rows. @@ -46,7 +46,7 @@ extern "C" #define MOBILEGL_SHARED_IMAGE_FOURCC_XBGR8888 0x34324258u /* 'XB24' */ /* ARGB8888 / XRGB8888: allocatable too. The layout of every shared image is the server's own * (modifier INVALID, never mapped), and channels are addressed logically by the GL that reads and - * writes them, so the name an image is allocated under never changes its colours. */ + * writes them, so the name an image is allocated under never changes its colors. */ #define MOBILEGL_SHARED_IMAGE_FOURCC_ARGB8888 0x34325241u /* 'AR24' */ #define MOBILEGL_SHARED_IMAGE_FOURCC_XRGB8888 0x34325258u /* 'XR24' */ /* Two-plane YUV 4:2:0 (ABI 2), when the server's platform allocates it (listed by diff --git a/MobileGL/MG_IntegrationTest/CMakeLists.txt b/MobileGL/MG_IntegrationTest/CMakeLists.txt index a86b5d9d..642bfeee 100644 --- a/MobileGL/MG_IntegrationTest/CMakeLists.txt +++ b/MobileGL/MG_IntegrationTest/CMakeLists.txt @@ -1866,7 +1866,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED) # ---- P3b/P4b espryt D1 slice 4: THE READBACK FAMILY ON THE SPLIT ARMS ------------------- # - # The 回读 half of the plan's "回读 / pack state" row. The PACK half is done - server reads + # The readback half of the plan's "readback / pack state" row. The PACK half is done - server reads # with neutral pack state, the client scatters (ID-49, EmitTables.cpp) - and the READBACK half # had no split coverage at all, so every claim about it was a reading of the code rather than # a run of it. Arming the lanes is the first half of the work and the census is the second: diff --git a/MobileGL/MG_IntegrationTest/Harness/BackendCapsPeek.h b/MobileGL/MG_IntegrationTest/Harness/BackendCapsPeek.h index 773b5dba..a2aeef40 100644 --- a/MobileGL/MG_IntegrationTest/Harness/BackendCapsPeek.h +++ b/MobileGL/MG_IntegrationTest/Harness/BackendCapsPeek.h @@ -11,7 +11,7 @@ // It exists for exactly one assertion: that the six per-axis compute limits the MGPipe // caps block carries (DynamicBackendParameters::MaxComputeWorkGroupCount/Size, plan B // section 4.4.1) are the same numbers glGetIntegeri_v answers today, since P0.5 retires -// the getter in favour of the caps. A separate translation unit, because the scenario +// the getter in favor of the caps. A separate translation unit, because the scenario // sources include the GL headers with prototypes and MobileGL's umbrella header is not // meant to meet them in one file. diff --git a/MobileGL/MG_IntegrationTest/Harness/HeadlessGL.cpp b/MobileGL/MG_IntegrationTest/Harness/HeadlessGL.cpp index 7734b40e..ecc57eab 100644 --- a/MobileGL/MG_IntegrationTest/Harness/HeadlessGL.cpp +++ b/MobileGL/MG_IntegrationTest/Harness/HeadlessGL.cpp @@ -431,7 +431,7 @@ namespace MGITest { return out.str(); } if (!WIFEXITED(status)) { - return "the EGL bring-up pre-flight child neither exited nor was signalled"; + return "the EGL bring-up pre-flight child neither exited nor was signaled"; } const int exitStatus = WEXITSTATUS(status); if (exitStatus != 0) { @@ -499,7 +499,7 @@ namespace MGITest { std::string Image::QuadrantSignature() const { if (m_width < 2 || m_height < 2) return ""; - // Quadrant CENTRES, so a one-pixel rounding difference at a quadrant edge + // Quadrant CENTERS, so a one-pixel rounding difference at a quadrant edge // never decides the answer. Order is fixed and load-bearing: bottom-left, // bottom-right, top-left, top-right. const int leftX = m_width / 4; diff --git a/MobileGL/MG_IntegrationTest/Harness/HeadlessGL.h b/MobileGL/MG_IntegrationTest/Harness/HeadlessGL.h index 367b8eb3..0cf0d276 100644 --- a/MobileGL/MG_IntegrationTest/Harness/HeadlessGL.h +++ b/MobileGL/MG_IntegrationTest/Harness/HeadlessGL.h @@ -59,7 +59,7 @@ namespace MGITest { bool operator!=(const Rgba8& other) const { return !(*this == other); } }; - // Prints as "rgba(255,0,0,255)" so a gtest failure names the colour it saw. + // Prints as "rgba(255,0,0,255)" so a gtest failure names the color it saw. std::ostream& operator<<(std::ostream& os, const Rgba8& c); // An RGBA8 readback. Row 0 is the BOTTOM row: that is GL's convention for @@ -88,14 +88,14 @@ namespace MGITest { // Count of differing bytes, for a failure message that says how wrong. std::size_t ByteDiffCount(const Image& other) const; - // The four quadrant centres, in the fixed order + // The four quadrant centers, in the fixed order // bottom-left, bottom-right, top-left, top-right. // // This replaces the old VerticalSignature(bandCount), which read three - // full-width horizontal stripes down the centre line and was therefore + // full-width horizontal stripes down the center line and was therefore // blind to an X flip, to a transpose, and to a 180 rotation composed with // a Y flip - all of those left the stripe order alone. Four quadrant - // colours are asymmetric in BOTH axes, so each of the eight square + // colors are asymmetric in BOTH axes, so each of the eight square // symmetries produces a different string (see OrientationScenario, which // spells all eight out). std::string QuadrantSignature() const; @@ -217,7 +217,7 @@ namespace MGITest { // ---- whole-region readback predicates ---------------------------------- // The scenarios used to assert on two or three individual pixels, which is // provably too weak: a draw in which 3 of a quad's 4 vertices carry stale - // data still paints the sampled centre the expected colour (that exact case + // data still paints the sampled center the expected color (that exact case // is a standing negative-control test - see CrossFrameBufferScenario). The // readback is already fully in memory, so counting every pixel in a region // costs nothing and turns "the middle looks right" into "all of it is right". @@ -237,7 +237,7 @@ namespace MGITest { // gtest predicate wrapper: EXPECT_TRUE(RegionIsMostly(...)) reports the // offender count, the offender fraction and the FIRST offending pixel's - // coordinates and colour. `tolerance` is the fraction of the region allowed + // coordinates and color. `tolerance` is the fraction of the region allowed // to disagree; pass 0.0 to demand every pixel (which is what the scenarios // do - they inset their regions away from primitive edges so exactness is // achievable). diff --git a/MobileGL/MG_IntegrationTest/Harness/PipeSlotPeek.h b/MobileGL/MG_IntegrationTest/Harness/PipeSlotPeek.h index b25f4657..4ec86fba 100644 --- a/MobileGL/MG_IntegrationTest/Harness/PipeSlotPeek.h +++ b/MobileGL/MG_IntegrationTest/Harness/PipeSlotPeek.h @@ -49,7 +49,7 @@ namespace MGITest { Texture, Renderbuffer, // Framebuffer has a HANDLE but no wire lifetime (D-I2): no create_*, no destroy row in - // the catalogue, and its death helper does the notice and the free and emits nothing. + // the catalog, and its death helper does the notice and the free and emits nothing. // That makes the allocator the ONLY observable of its lifetime, so this row matters // more here than the others rather than less. Framebuffer, diff --git a/MobileGL/MG_IntegrationTest/Harness/PipeStatsWindow.h b/MobileGL/MG_IntegrationTest/Harness/PipeStatsWindow.h index 25f19cbf..8a169fea 100644 --- a/MobileGL/MG_IntegrationTest/Harness/PipeStatsWindow.h +++ b/MobileGL/MG_IntegrationTest/Harness/PipeStatsWindow.h @@ -254,7 +254,7 @@ namespace MGITest::PipeStatsWindow { // One counter out of that line, by its short name ("mpr", "draws", "csom"), or -1 when the // line does not carry it. The search includes the SEPARATOR before the name and the `=` after // it, so "draws" cannot match "draws/f=" and "mpr" cannot match a longer name ending in it - - // a substring match here would read a neighbouring counter's value and report it as this + // a substring match here would read a neighboring counter's value and report it as this // one's, which is the one way a counter assertion can be wrong without ever failing. inline long long CounterOrAbsent(const Window& window, const char* shortName) { if (!window.found) return -1; diff --git a/MobileGL/MG_IntegrationTest/Harness/ScenarioFixture.h b/MobileGL/MG_IntegrationTest/Harness/ScenarioFixture.h index b47eecd3..34d32803 100644 --- a/MobileGL/MG_IntegrationTest/Harness/ScenarioFixture.h +++ b/MobileGL/MG_IntegrationTest/Harness/ScenarioFixture.h @@ -75,7 +75,7 @@ namespace MGITest { class ScenarioTest : public ::testing::Test { protected: - // THE BEHAVIOURAL HALF OF THE SPLIT LANE'S CLAIM, and it is in the DESTRUCTOR rather than + // THE BEHAVIORAL HALF OF THE SPLIT LANE'S CLAIM, and it is in the DESTRUCTOR rather than // in TearDown() on purpose: gtest calls only the MOST DERIVED TearDown, and every scenario // that overrides it would have to remember to chain here. The fixture destructor always // runs, and it runs before the test result is finalized, so ADD_FAILURE() is recorded. diff --git a/MobileGL/MG_IntegrationTest/Harness/SplitLane.h b/MobileGL/MG_IntegrationTest/Harness/SplitLane.h index e21bc6ca..b3c446f0 100644 --- a/MobileGL/MG_IntegrationTest/Harness/SplitLane.h +++ b/MobileGL/MG_IntegrationTest/Harness/SplitLane.h @@ -12,7 +12,7 @@ // GOT it is a different question and it is answered by Harness/SplitRuntimePeek.h, out of the // running process - see the long argument in that header. The split of responsibility matters: // an environment variable is a request, and this package's first version treated a request (plus -// a grep over source text) as evidence that the request had been honoured. Review finding M-1 +// a grep over source text) as evidence that the request had been honored. Review finding M-1 // falsified that by renaming one string in six files, which armed eleven lanes and turned eight // of them green against the monolith path. // @@ -71,7 +71,7 @@ namespace MGITest::SplitLane { } // Empty when this case may assert; otherwise the reason to GTEST_SKIP() with. The reason is - // spelled out rather than summarised because a skip line is the only thing anyone reads when + // spelled out rather than summarized because a skip line is the only thing anyone reads when // they ask "did the split lane actually run" - and because the previous version of this // message named the wrong missing thing (review finding N-1): it said MG_Remote/Client did // not exist, on a tree where it existed and compiled and every entry point aborted. diff --git a/MobileGL/MG_IntegrationTest/Harness/SplitRuntimePeek.h b/MobileGL/MG_IntegrationTest/Harness/SplitRuntimePeek.h index 1977ca27..d869ff5d 100644 --- a/MobileGL/MG_IntegrationTest/Harness/SplitRuntimePeek.h +++ b/MobileGL/MG_IntegrationTest/Harness/SplitRuntimePeek.h @@ -39,7 +39,7 @@ // job of making "a table that silently lost an emitter" distinguishable from "a table that // never had one" (EmitTables.h). Zero means there is no emitter to test. // -// And one BEHAVIOURAL fact, which is the half that says the run went through the wire rather than +// And one BEHAVIORAL fact, which is the half that says the run went through the wire rather than // merely that it could have: `ClientSession::Active()->Encoder().EmitSeq()`, the highest record // ordinal this client has produced. A scenario that armed, drew, and emitted nothing has a // sequence that did not move, and that is the shape of an emit table that resolves the transport diff --git a/MobileGL/MG_IntegrationTest/Harness/WireLedgerChecks.h b/MobileGL/MG_IntegrationTest/Harness/WireLedgerChecks.h index 4d16a09b..5de04fa7 100644 --- a/MobileGL/MG_IntegrationTest/Harness/WireLedgerChecks.h +++ b/MobileGL/MG_IntegrationTest/Harness/WireLedgerChecks.h @@ -16,7 +16,7 @@ // Half of that proof is already a Fatal - PipeWireCodec.cpp aborts Fatal{RingOverrun} on a // record ABOVE the cap - and it is the loud half. The quiet half is the one this assertion // covers: the phase has to publish the MAXIMUM ACTUALLY SEEN on a real workload, so that a -// record creeping towards the cap is visible before the day it crosses. Until this landed the +// record creeping toward the cap is visible before the day it crosses. Until this landed the // only readers of PipeWireEncoder::MaxRecordBytesSeen() were codec unit cases over synthetic // records, and the joint gate recorded BRIEF 8 item 3 as "Maximum record bytes: NO MEASUREMENT" // (joint-v1.md 5). @@ -24,7 +24,7 @@ // R-9 / exit gate E3(e) (ExpectSmallRingWrappedAtLeastOnce). The SmallRing lane exists to run // the reduced path over a ring small enough to force the wrap path - the kRecPad filler that // both sides must SKIP WITHOUT ADVANCING seq, which is R-9's last clause and the one piece of -// ring behaviour no other lane reaches. It ran green from the day it was registered and proved +// ring behavior no other lane reaches. It ran green from the day it was registered and proved // nothing, because nobody counted: measured on the joint head, a whole split scenario writes // about 40 KiB into SEG_CMD (emitseq 22-71, maxrec 784 bytes), so a 1 MiB "small" ring is 25 // times larger than the traffic and the head never comes near its wrap boundary. The lane and @@ -45,7 +45,7 @@ // trips round the ring and ZERO pads. The reason is arithmetic, not a defect - a workload whose // records repeat at a uniform stride that divides a power-of-two capacity lands on the boundary // exactly, every time - so a gate written against the pad count would have been red for the -// sizes in the record catalogue and green the day one of them changed. The pad count is +// sizes in the record catalog and green the day one of them changed. The pad count is // RECORDED beside the wrap count (ringpads= on the stats line, in the JUnit properties, and in // the session's teardown ledger) so the number is available without being load-bearing. diff --git a/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py b/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py index 99839b56..0ae5cf2f 100644 --- a/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py +++ b/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py @@ -385,7 +385,7 @@ def verify_split_arming(logs_dir, junit_path, expected_path): applied to arming: * an entry whose client log carries the arming line is ARMED and needs nothing else; - * an entry that ctest reported SKIPPED is recognised without a name - a gtest skip is a + * an entry that ctest reported SKIPPED is recognized without a name - a gtest skip is a process that brought a session up and left before any verb, which is honestly unarmed, and the skip set is driver-dependent (a GitHub runner's lavapipe/llvmpipe skips more or fewer than the host's), so naming those would ratchet on the driver; diff --git a/MobileGL/MG_IntegrationTest/Harness/test_split_log_paths.py b/MobileGL/MG_IntegrationTest/Harness/test_split_log_paths.py index 3002fa9b..9441a30a 100644 --- a/MobileGL/MG_IntegrationTest/Harness/test_split_log_paths.py +++ b/MobileGL/MG_IntegrationTest/Harness/test_split_log_paths.py @@ -324,7 +324,7 @@ class IpcConfigProofTest(unittest.TestCase): pins, line = self.inproc(ra="0") self.assertEqual(self.check([("A", "pass", pins + ["MOBILEGL_IPC_RUN_AHEAD=0"], line)]), 0) self.assertEqual(self.check([("A", "pass", pins + ["MOBILEGL_IPC_RUN_AHEAD=1"], line)]), 1, - "a pinned value the run did not honour is red, not a changed default") + "a pinned value the run did not honor is red, not a changed default") def test_the_value_is_matched_whole(self): pins, line = self.inproc(ra="10") diff --git a/MobileGL/MG_IntegrationTest/P8Coverage.cmake b/MobileGL/MG_IntegrationTest/P8Coverage.cmake index 31c862a7..ec344d6e 100644 --- a/MobileGL/MG_IntegrationTest/P8Coverage.cmake +++ b/MobileGL/MG_IntegrationTest/P8Coverage.cmake @@ -182,7 +182,7 @@ set(MGL_P8A_KNOB_FILTER_PointSizeDemotion "PointSizeDemotionScenario.*") set(MGL_P8A_KNOB_ENV_PointSizeDemotion "MOBILEGL_POINT_SIZE_DEMOTION=1") set(MGL_P8A_KNOB_FILTER_UnlocatedIoBlocks "UnlocatedIoBlockScenario.*") set(MGL_P8A_KNOB_ENV_UnlocatedIoBlocks "MOBILEGL_ESPRYT_UNLOCATED_IO_BLOCKS=1") -# One case, as on monolith: the three positive cases describe behaviour the backend does not +# One case, as on monolith: the three positive cases describe behavior the backend does not # have with the emulation off. set(MGL_P8A_KNOB_FILTER_NoViewportArrayEmulation "ViewportArrayScenario.WithoutTheEmulationEveryIndexCollapsesOntoViewportZero") diff --git a/MobileGL/MG_IntegrationTest/Scenarios/AdvertisedLimitsScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/AdvertisedLimitsScenario.cpp index bc5372b8..3bde46fb 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/AdvertisedLimitsScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/AdvertisedLimitsScenario.cpp @@ -616,7 +616,7 @@ void main() { g_data[gl_LocalInvocationIndex] = 1u; } << axis.name << "[" << i << "]: MGPCaps carries " << capsAxis[i] << " but glGetIntegeri_v answers " << indexed[i] << " - the caps block and the getter path must be one number, because P0.5 retires " - "the getter in favour of the caps"; + "the getter in favor of the caps"; } } } diff --git a/MobileGL/MG_IntegrationTest/Scenarios/AsyncCompileScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/AsyncCompileScenario.cpp index 4e3a9fce..c91fdea0 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/AsyncCompileScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/AsyncCompileScenario.cpp @@ -569,7 +569,7 @@ void main() { // Distinct per program (so neither the source memo nor the adoption map turns // a compile into a no-op) but a pure pass-through at runtime: the bulk sits in - // a branch a zero-initialised uniform never takes. + // a branch a zero-initialized uniform never takes. const auto fragmentSource = [](const int index) { std::string source = "#version 330 core\nin vec3 vColor;\nout vec4 oColor;\n"; source += "uniform float uGate" + std::to_string(index) + ";\n"; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/AtomicCounterScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/AtomicCounterScenario.cpp index 0f677260..25d87572 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/AtomicCounterScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/AtomicCounterScenario.cpp @@ -49,7 +49,7 @@ namespace MGITest { // Two counters share binding 0 at DIFFERENT offsets and a third sits alone on binding 1. // The offsets are what separates "the buffer arrived" from "the buffer arrived and the // block is laid out the way GL says": a lowering that packed the members in declaration - // order without honouring `offset` would still pass a single-counter check. + // order without honoring `offset` would still pass a single-counter check. constexpr const char* kCounterComputeSource = R"(#version 430 core layout(local_size_x = 4) in; layout(binding = 0, offset = 0) uniform atomic_uint g_first; @@ -294,7 +294,7 @@ void main() { << "offset 0 read back " << values[0] << "; the SubData did not reach the second dispatch"; EXPECT_EQ(values[1], 4 * kInvocations) << "offset 4 read back " << values[1] << "; " << 2 * kInvocations - << " means the drain before the second dispatch rewrote the shader-written neighbour from the " + << " means the drain before the second dispatch rewrote the shader-written neighbor from the " << "stale host copy"; } diff --git a/MobileGL/MG_IntegrationTest/Scenarios/BandedReadbackScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/BandedReadbackScenario.cpp index e2c2e884..1527b859 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/BandedReadbackScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/BandedReadbackScenario.cpp @@ -203,7 +203,7 @@ namespace MGITest { // THE CTS SHAPE, byte for byte: KHR-GL46.direct_state_access.renderbuffers_storage reads a // 256x512 RGBA32F renderbuffer as GL_RGBA/GL_FLOAT - 2,097,152 bytes, sixteen more than a slot. // A renderbuffer cannot be uploaded, so it is painted with scissored clears: 16 row stripes x 2 - // column halves, each its own colour (every value a multiple of 1/32, exact in float and inside + // column halves, each its own color (every value a multiple of 1/32, exact in float and inside // [0, 1] so no backend's clamping can move it). The last band is the single top row. TEST_F(BandedReadbackScenario, RenderbufferReadOfExactlyTwoMiBIsBandedNotRefused) { if (!Ready()) return; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ClearOrderScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ClearOrderScenario.cpp index dc84275d..92a2f0a5 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ClearOrderScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ClearOrderScenario.cpp @@ -9,15 +9,15 @@ // Scenario - A CLEAR TAKES EFFECT WHERE THE APPLICATION ISSUED IT, WHICHEVER FRAMEBUFFER IT WENT THROUGH. // // Minecraft clears its targets through framebuffers of their own (a depth-only one for the shared -// depth texture, one per colour target) and draws through another framebuffer holding the same +// depth texture, one per color target) and draws through another framebuffer holding the same // textures. Magma keeps such a clear on the image and folds it into the load op of the next pass // that draws into the image, records it inside the open pass when that pass holds the image, and // runs it before any other use (sampling, blit, readback, upload, respecify). Each case below is // one of those paths, with no readback between the clear and the work that depends on it: // - a depth clear through a depth-only framebuffer, then a depth-tested draw through the main one // (folded into the next pass), and the same while the main pass is open (inside it); -// - a colour clear through a framebuffer of its own, then a draw covering half the texture -// through another framebuffer holding it (the other half keeps the clear colour); +// - a color clear through a framebuffer of its own, then a draw covering half the texture +// through another framebuffer holding it (the other half keeps the clear color); // - a cleared texture sampled, blitted from, uploaded into, read back and re-specified before // any pass draws into it; // - a scissored clear, which clears only its box. @@ -190,7 +190,7 @@ void main() { color = tint; })"; EXPECT_EQ(FirstGLError(), GLenum(GL_NO_ERROR)) << why; } - // Main framebuffer (colour + depth) and a depth-only clear framebuffer sharing its depth. + // Main framebuffer (color + depth) and a depth-only clear framebuffer sharing its depth. struct Pair { GLuint color, depth, main, depthOnly; }; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ClearThenReadPixelsScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ClearThenReadPixelsScenario.cpp index 319701d9..86fdf39f 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ClearThenReadPixelsScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ClearThenReadPixelsScenario.cpp @@ -12,7 +12,7 @@ // loadOp. When nothing is drawn after the clear there is no render pass, and the readback path // used to materialize pending clears only for USER framebuffers - so a readback right after a // clear of the DEFAULT framebuffer blitted the untouched swapchain image and handed back the -// previous frame's colour. +// previous frame's color. // // That is the whole of KHR-GL40.draw_indirect.negative-* (12 Magma failures): each case clears, // issues a draw that correctly raises INVALID_OPERATION and therefore never executes, then reads @@ -49,7 +49,7 @@ in vec2 aPos; void main() { gl_Position = vec4(aPos, 0.0, 1.0); } )"; - // The colour KHR-GL40.draw_indirect's fshSimple paints, so a stale readback shows up as + // The color KHR-GL40.draw_indirect's fshSimple paints, so a stale readback shows up as // the same value the conformance log reports. constexpr const char* kFS = R"(#version 330 core out vec4 o_color; @@ -208,7 +208,7 @@ void main() { o_color = vec4(0.1, 0.2, 0.3, 1.0); } DrawFullViewportQuad(program); // Clear the DEFAULT framebuffer, then blit the source over it. The clear is white so a - // frame that lost the blit is unmistakable, and the blit's colour is fshSimple's. + // frame that lost the blit is unmistakable, and the blit's color is fshSimple's. BindDefaultFramebuffer(); glViewport(0, 0, width, height); ClearTo(1.0f, 1.0f, 1.0f, 1.0f); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ClientVertexArrayScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ClientVertexArrayScenario.cpp index b862c7e8..1431a7f8 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ClientVertexArrayScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ClientVertexArrayScenario.cpp @@ -147,10 +147,10 @@ void main() { o_color = vec4(0.0, 1.0, 0.0, 1.0); } const Rgba8 centre = CentreAfter(width, height); EXPECT_GT(static_cast(centre.g), 200) - << "the client-memory vertex array never reached the draw: the centre is " << centre - << ", i.e. still the clear colour. The draw did not consume its owned client-vertex snapshot"; + << "the client-memory vertex array never reached the draw: the center is " << centre + << ", i.e. still the clear color. The draw did not consume its owned client-vertex snapshot"; EXPECT_LT(static_cast(centre.b), 60) - << "the quad drew, but the clear colour is still showing through: " << centre; + << "the quad drew, but the clear color is still showing through: " << centre; quad.Release(); glUseProgram(0); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ClipControlScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ClipControlScenario.cpp index e06354cd..9ecc94d9 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ClipControlScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ClipControlScenario.cpp @@ -10,7 +10,7 @@ // // The state used to be recorded and reported back by glGet but never applied, so an upper-left // origin drew the right way up and a [0, 1] depth mode kept GL's [-1, 1] clip volume. Each case -// below is a colour-only observable of one half of the extension: +// below is a color-only observable of one half of the extension: // // - origin: a primitive in the lower half of clip space lands in the TOP half of the window // under GL_UPPER_LEFT, on the default framebuffer (which DirectVulkan stores flipped already) diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ClipDistanceScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ClipDistanceScenario.cpp index 94aff76b..ec62517e 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ClipDistanceScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ClipDistanceScenario.cpp @@ -18,7 +18,7 @@ // KHR-GLxx.clip_distance.functional. glIsEnabled lied about it too - it returned GL_FALSE // immediately after a successful glEnable. // -// The assertions are behavioural, not query-shaped, because a query-only test passes against a +// The assertions are behavioral, not query-shaped, because a query-only test passes against a // backend that stores the bit and never forwards it. Each case draws one full-viewport triangle // whose clip distance is positive on one side of the viewport and negative on the other, then // checks BOTH sides: the kept side proves the draw happened at all, and the clipped side is the @@ -31,7 +31,7 @@ // clip by EVERY declared gl_ClipDistance regardless of the enables, so // AnEnabledClipDistanceRemovesTheNegativeHalf goes green there against the broken tree as well, // and the two cases that need real per-distance semantics skip (see -// DriverHonoursPerDistanceEnables). What actually pins the behaviour is Adreno, through +// DriverHonoursPerDistanceEnables). What actually pins the behavior is Adreno, through // KHR-GLxx.clip_distance.functional - whose "without dynamic redeclaration" variants declare all // gl_MaxClipDistances slots and enable only the first N, i.e. exactly the subset semantics these // skipped cases assert. Read a green CI run here as "the state survives the frontend", not as @@ -171,7 +171,7 @@ void main() { fragColor = vec4(0.0, 1.0, 0.0, 1.0); } // state, i.e. when a written-but-disabled gl_ClipDistance leaves its fragments // alone. Not every stack does, and the difference is not MobileGL's to hide: // - // - Adreno's ES driver honours GL_CLIP_DISTANCE0_EXT..7_EXT, which is what makes + // - Adreno's ES driver honors GL_CLIP_DISTANCE0_EXT..7_EXT, which is what makes // KHR-GLxx.clip_distance.functional pass on the device once the enables are // forwarded at all. // - Vulkan has no such state: every clip distance a shader declares is active, diff --git a/MobileGL/MG_IntegrationTest/Scenarios/CopyImageLayeredScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/CopyImageLayeredScenario.cpp index 707011be..0aa283d4 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/CopyImageLayeredScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/CopyImageLayeredScenario.cpp @@ -113,7 +113,7 @@ namespace MGITest { } // A trivial 1x1x1 array-to-array copy: it exercises the entry point without depending - // on any of the behaviour under test, so a driver (or a backend function table) that + // on any of the behavior under test, so a driver (or a backend function table) that // simply does not have the call skips instead of failing every case below. bool CopyImageSubDataUsable() { GLuint probe[2] = {0, 0}; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/CopyImagePacked16Scenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/CopyImagePacked16Scenario.cpp index 687448c7..c1319075 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/CopyImagePacked16Scenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/CopyImagePacked16Scenario.cpp @@ -38,7 +38,7 @@ // // This scenario runs in BOTH configurations, and both must hand back identical client words: // * the ambient registrations take the narrow path on a clean driver (llvmpipe has no -// mirror, so Auto keeps the native 16-bit storage - the pre-existing behaviour stays +// mirror, so Auto keeps the native 16-bit storage - the pre-existing behavior stays // covered); // * the DirectGLES.WidenedPacked16. registration pins MOBILEGL_ESPRYT_WIDEN_PACKED16_STORAGE=1, // which is the storage every affected device will actually run - without it the repair @@ -74,7 +74,7 @@ namespace MGITest { constexpr int kLayers = 12; constexpr int kFlatSize = 7; // the plain-2D / renderbuffer endpoint, level 0 // Copies cover the whole flat endpoint and land at (8, 8) inside the 15x15 level so - // that offsets are honoured, not just texel (0, 0): 8 + 7 == 15 reaches the far edge. + // that offsets are honored, not just texel (0, 0): 8 + 7 == 15 reaches the far edge. constexpr int kRegion = kFlatSize; constexpr int kArrayOffset = 8; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/CopyImageStoreReadbackScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/CopyImageStoreReadbackScenario.cpp index df02b7ed..48244259 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/CopyImageStoreReadbackScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/CopyImageStoreReadbackScenario.cpp @@ -10,7 +10,7 @@ // the phase notes). // // The formats are the ones an ES driver keeps as texture-only storage: GL_RGB16 (EXT_texture_norm16 -// makes the three-channel spelling sampleable, never colour-renderable) and the 16-bit SNORM family +// makes the three-channel spelling sampleable, never color-renderable) and the 16-bit SNORM family // (renderable only with EXT_render_snorm, which Adreno does not have). Their glGetTexImage cannot go // through a framebuffer on such a driver, so something other than the GPU image has to answer it: // the CPU shadow on the monolith arm, the server's staged store on a split one. A copy writes the @@ -25,7 +25,7 @@ // has no store route to exercise. // // THE KNOB. MGITEST_ESPRYT_REFUSE_TEXTURE_READBACK_EXTENT=x is read BY THE ESPRYT SERVER -// (DirectGLESReadback.cpp, ReadTextureImageWire): a colour level of exactly that extent is +// (DirectGLESReadback.cpp, ReadTextureImageWire): a color level of exactly that extent is // treated as a level the driver refused to attach - what a driver without EXT_texture_norm16 / // EXT_render_snorm does for these formats (an Adreno 750, which has both, reads them all back // through the GPU; measured in P13), and what llvmpipe can be made to do no other way. The @@ -88,7 +88,7 @@ namespace MGITest { return format.components == 0 ? 4 : format.components * 2; } - // Every word differs from its neighbours and from the other patterns, so a mis-addressed + // Every word differs from its neighbors and from the other patterns, so a mis-addressed // row, a swapped endpoint or a copy that never happened cannot cancel out. SNORM never // gets -32768: it and -32767 are the same value (-1.0), and a read that goes through a // normalized float is entitled to answer either. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/CrossFrameBufferScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/CrossFrameBufferScenario.cpp index f4f27edc..43f9a4f1 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/CrossFrameBufferScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/CrossFrameBufferScenario.cpp @@ -30,10 +30,10 @@ // indices A {0,1,2, 0,2,3} -> the left, red quad // indices B {4,5,6, 4,6,7} -> the right, green quad // -// A vertex-buffer test rewrites the left quad's colour red -> green and expects +// A vertex-buffer test rewrites the left quad's color red -> green and expects // the left half to turn green. An index-buffer test rewrites the indices // A -> B and expects the picture to jump from a red left half to a green right -// half. Either way "stale" and "fresh" are different colours in different +// half. Either way "stale" and "fresh" are different colors in different // places; no thresholds, no interpretation. // // Two families of scenario live here, and they catch different halves of the @@ -130,10 +130,10 @@ void main() { // Asserts the left and right halves of the viewport, with a message that // says what the app had asked GL to draw by then. // - // This counts EVERY pixel in each half rather than sampling its centre. + // This counts EVERY pixel in each half rather than sampling its center. // Sampling two pixels was demonstrably too weak: a draw in which three of - // the left quad's four vertices still carry stale data paints a centre - // pixel of exactly the expected colour and passed the old assertion. That + // the left quad's four vertices still carry stale data paints a center + // pixel of exactly the expected color and passed the old assertion. That // case is now a standing negative control - see // PartialStalenessIsCaughtByWholeRegionChecks below, which constructs it // deliberately and proves the region scan reports it. @@ -555,20 +555,20 @@ void main() { } // Every case above leans on ExpectHalves. ExpectHalves used to sample the - // centre pixel of each half - two pixels for a 12288-pixel readback - and + // center pixel of each half - two pixels for a 12288-pixel readback - and // that is measurably too weak to stand behind a claim about buffer // freshness: a quad whose four vertices are only PARTLY updated still - // paints a sampled centre the expected colour, because the centre is a + // paints a sampled center the expected color, because the center is a // barycentric blend dominated by the vertices that DID update. // - // So construct that case on purpose. Update the left quad's colour to + // So construct that case on purpose. Update the left quad's color to // green in the buffer but leave exactly one of its four vertices holding // the old red, once for each vertex, and check two things: // // - the whole-region scan reports every one of the four (the tightening // is real, and this test fails the moment someone loosens it back to // sampling); - // - at least one of the four is invisible to a single centre sample + // - at least one of the four is invisible to a single center sample // (the blind spot was real, and this records which vertices it hid). // // Nothing here calls a memo path; it is the assertion itself under test. @@ -602,7 +602,7 @@ void main() { const RegionScan scan = ScanRegion(image, kHalfInset, w / 2 - kHalfInset, kHalfInset, h - kHalfInset, "green"); EXPECT_GT(scan.offenders, 0) - << "vertex " << staleVertex << " of the left quad kept its stale red colour and the " + << "vertex " << staleVertex << " of the left quad kept its stale red color and the " << "whole-region scan saw nothing wrong across " << scan.total << " pixels - the assertion " << "is not tight enough to stand behind any freshness claim in this file"; @@ -615,12 +615,12 @@ void main() { } EXPECT_GT(centreSampleMissed, 0) - << "no single-vertex staleness was invisible to a centre sample, so this negative control " + << "no single-vertex staleness was invisible to a center sample, so this negative control " << "is no longer demonstrating anything - re-derive it before trusting it"; if (centreSampleMissed > 0) { RecordProperty("centre_sample_blind_to_stale_vertices", missedVertices); std::fprintf(stderr, - "[itest] whole-region scan caught all %d single-stale-vertex cases; a centre " + "[itest] whole-region scan caught all %d single-stale-vertex cases; a center " "sample alone was blind to %d of them (vertices %s)\n", kLeftQuadVertexCount, centreSampleMissed, missedVertices.c_str()); } @@ -727,7 +727,7 @@ void main() { StreamedObject m_decoy; }; - // Vertex data. Subject and decoy differ in geometry AND colour, so a + // Vertex data. Subject and decoy differ in geometry AND color, so a // subject draw that reads the decoy's arena bytes paints the decoy's quad. TEST_F(StreamedArenaScenario, StreamedVertexDataSurvivesArenaRecycling) { const std::vector full = SceneVertices(/*leftQuadIsGreen=*/false); @@ -783,7 +783,7 @@ void main() { // // It stays because it is the tripwire for the change that would make the // EBO memo dangerous: memoise the streamed index path - the obvious next - // step for the same optimisation - and the reach stops being zero and this + // step for the same optimization - and the reach stops being zero and this // test fails on the first churn frame. See ResidentIndexScenario.cpp. TEST_F(StreamedArenaScenario, StreamedIndexDataSurvivesArenaRecycling) { const std::vector shared = SceneVertices(/*leftQuadIsGreen=*/false); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/CsoContentAddressingScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/CsoContentAddressingScenario.cpp index bd586d66..90c60203 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/CsoContentAddressingScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/CsoContentAddressingScenario.cpp @@ -33,7 +33,7 @@ // both arms // The PIXELS must not move. The quad is drawn with alpha 1.0 through // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA, so the blended and unblended draws produce the -// same colour by construction and the readback is the same image in both arms and after +// same color by construction and the readback is the same image in both arms and after // every toggle. "The counters moved and the picture did not" is the whole claim. // // HOW THE COUNTERS ARE READ. MG_Util::PipeStats is internal to the library and this module cannot @@ -42,7 +42,7 @@ // so each lane sets MOBILEGL_PIPE_STATS=1, MOBILEGL_PIPE_STATS_PERIOD=1 - one line per // eglSwapBuffers - and a MOBILEGL_LOG_FILE_PATH of its OWN. The log path has to be private: the // library opens it fopen(path, "w"), so every process in a lane truncates it, and a whole-file -// read in a shared lane races a neighbour's bring-up. That is the same rule, and the same +// read in a shared lane races a neighbor's bring-up. That is the same rule, and the same // remedy, as PipeVerifyArmingScenario's arming lane. // // The window a summary line reports is "since the previous line" (PipeStats::FormatWindowLine), so diff --git a/MobileGL/MG_IntegrationTest/Scenarios/CtWireScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/CtWireScenario.cpp index 1c4c0e81..7f2fb279 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/CtWireScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/CtWireScenario.cpp @@ -16,7 +16,7 @@ // ScenarioFixture's emit-ordinal rule. // // object_death (§5.2): a texture and a framebuffer die, the deaths cross, and the slots -// recycle. The picture after recycling is the behavioural half: a stale twin answering for +// recycle. The picture after recycling is the behavioral half: a stale twin answering for // the recycled object renders the DEAD object's content (or errors), which is the exact // shape LiveGenAt's generation check exists to refuse. // @@ -333,7 +333,7 @@ namespace MGITest { } glDeleteRenderbuffers(1, &renderbuffer); - // Recycle: a new FBO and a new backing store, cleared to a different colour. A stale + // Recycle: a new FBO and a new backing store, cleared to a different color. A stale // twin answering for the recycled framebuffer renders the blue of the dead one. glGenFramebuffers(1, &fbo); glGenRenderbuffers(1, &renderbuffer); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DefaultFramebufferAcrossSwapScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DefaultFramebufferAcrossSwapScenario.cpp index d7d1b22c..e14ecb17 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DefaultFramebufferAcrossSwapScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DefaultFramebufferAcrossSwapScenario.cpp @@ -23,7 +23,7 @@ // // Two claims, and neither can be satisfied by ignoring the other: // -// * a readback issued after a swap, with no draw in between, still sees the colour the +// * a readback issued after a swap, with no draw in between, still sees the color the // app drew into the default framebuffer (that is the retrace snapshot's frame); // * the NEXT draw into the default framebuffer does land in the image the readback then // resolves - i.e. the write re-points the default framebuffer at what Present() @@ -69,8 +69,8 @@ void main() { o_color = vColor; } class DefaultFramebufferAcrossSwapScenario : public ScenarioTest {}; // One interleaved VBO: aPos (vec2) then aColor (vec4). CompileProgram pins those two - // attribute names to locations 0 and 1. The colours below are fully saturated or fully - // off, so the readback lands on a named colour whatever the driver's exact rounding is. + // attribute names to locations 0 and 1. The colors below are fully saturated or fully + // off, so the readback lands on a named color whatever the driver's exact rounding is. void DrawFullViewportQuad(unsigned int program, float red, float green, float blue) { const float vertices[] = { -1.0f, -1.0f, red, green, blue, 1.0f, 1.0f, -1.0f, red, green, blue, 1.0f, diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DeletedBoundBufferScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DeletedBoundBufferScenario.cpp index 4989236a..21c97b9b 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DeletedBoundBufferScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DeletedBoundBufferScenario.cpp @@ -324,7 +324,7 @@ void main() { // Transform feedback: nothing re-sends a capture window at a draw today (bit 17 is computed and // not emitted), so the stale-handle failure cannot reach the backend through this target; the - // case pins the behaviour anyway - the delete unbinds, a draw after the slot is reused runs, + // case pins the behavior anyway - the delete unbinds, a draw after the slot is reused runs, // and a fresh capture buffer at the same point receives exactly the captured values. TEST_F(DeletedBoundBufferScenario, ATransformFeedbackBufferDeletedWhileBoundLeavesNoStaleBinding) { if (!Ready() || IsSkipped()) return; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackAttachmentShapeScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackAttachmentShapeScenario.cpp index 11275841..6ea0ac10 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackAttachmentShapeScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackAttachmentShapeScenario.cpp @@ -10,7 +10,7 @@ // AND THE DEFAULT FRAMEBUFFER'S ADVERTISED DEPTH/STENCIL FORMAT. // // Three shipped defects, all of them invisible to a test that only ever attaches a 2D texture -// or only ever asks the default framebuffer for a colour value. +// or only ever asks the default framebuffer for a color value. // // (1) The ES depth/stencil readback emulation identifies the source format by binding the // attachment's texture NAME to GL_TEXTURE_2D and asking that target for its internal @@ -32,7 +32,7 @@ // GL blits depth/stencil only between IDENTICAL formats, so an application that reads // GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, allocates the buffer it was just told about and // blits gets GL_INVALID_OPERATION - and a rejected glBlitFramebuffer transfers NOTHING, -// colour bits included. DirectVulkan has published its real format since the swapchain +// color bits included. DirectVulkan has published its real format since the swapchain // work; this is the half that was missing. // // Every case poisons its destination with a value the correct answer cannot be, so "the @@ -85,7 +85,7 @@ namespace MGITest { } // Clears the currently bound framebuffer's depth and stencil to the shared - // reference values, with both write masks explicitly open (glClear honours them, + // reference values, with both write masks explicitly open (glClear honors them, // and a leftover mask from another scenario in this shared context would look // exactly like the bug under test). void ClearDepthStencil() const { @@ -310,7 +310,7 @@ namespace MGITest { EXPECT_EQ(FirstGLError(), 0u); ASSERT_TRUE(FramebufferIsComplete()); - // Put a known depth in the default framebuffer, then blit colour+depth+stencil out of + // Put a known depth in the default framebuffer, then blit color+depth+stencil out of // it into the buffer that its own description asked for. BindDefaultFramebuffer(); glViewport(0, 0, width, height); @@ -334,9 +334,9 @@ namespace MGITest { const float depth = ReadDepthAt(width / 2, height / 2); const int stencil = ReadStencilAt(width / 2, height / 2); EXPECT_EQ(FirstGLError(), 0u); - // The colour bit is the precondition, not the claim: it says this stack can blit out of + // The color bit is the precondition, not the claim: it says this stack can blit out of // its default framebuffer at all, which has nothing to do with depth/stencil formats. - // DirectVulkan on a surfaceless pbuffer cannot - the whole call, colour included, is a + // DirectVulkan on a surfaceless pbuffer cannot - the whole call, color included, is a // no-op there, while the same blit works on a real surface (KHR-GLxx.framebuffer_blit // exercises exactly it and Magma passes 33/33 on device). Skipping keeps the // depth/stencil claim below falsifiable instead of drowning it in an unrelated @@ -351,7 +351,7 @@ namespace MGITest { glDeleteRenderbuffers(1, &depthRbo); gl.EndFrame(); GTEST_SKIP() << "backend " << gl.BackendName() - << " on this surface transferred no colour either (green=" << int(color[1]) + << " on this surface transferred no color either (green=" << int(color[1]) << "): it cannot blit out of the default framebuffer here, so the depth/stencil half proves " "nothing. The GL-error assertion above still ran, and it is the format contract"; } diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackMatrixScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackMatrixScenario.cpp index 91c3c0ea..93adb7ef 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackMatrixScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackMatrixScenario.cpp @@ -111,7 +111,7 @@ namespace MGITest { internalFormat == GL_STENCIL_INDEX8; } - // A framebuffer whose depth/stencil lives in a TEXTURE. The colour attachment is + // A framebuffer whose depth/stencil lives in a TEXTURE. The color attachment is // there so a stencil-only or depth-only framebuffer still has something to size it. DepthSource MakeTextureSource(GLenum internalFormat) { DepthSource source; @@ -203,7 +203,7 @@ namespace MGITest { // "every value in the region is `expected`" rather than "the middle pixel is": // a staging blit that lands the wrong rectangle, or a conversion pass with a - // half-texel offset, still gets the centre right. + // half-texel offset, still gets the center right. static void ExpectAllDepth(const std::vector& values, float expected, const char* what) { size_t bad = 0; float worst = expected; @@ -532,14 +532,14 @@ namespace MGITest { // on both: `Magma:multisample-depth-resolve-region` covered the reversed rectangle and the // scaled one under one Fatal. // - // COLOUR AND DEPTH IN ONE CALL, because that is the shape that made this visible: the colour + // COLOR AND DEPTH IN ONE CALL, because that is the shape that made this visible: the color // arm has handled a flip since P5f and handles a scale as of this package, so - // GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT resolved its colour correctly and then died on its + // GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT resolved its color correctly and then died on its // depth. Asserting both aspects of the same blit is what pins them together. // // THE BANDS ARE UNEQUAL ON PURPOSE (0.25 bottom / 0.75 top): a flip that did not happen // returns the bands the right way up, and a "flip" that merely reordered the readback would - // move the colour too - so colour and depth are checked to agree about which way up they are. + // move the color too - so color and depth are checked to agree about which way up they are. // // THE CASE IS ARMED ON THE MAGMA WIRE ARM ONLY, and the two gates below say which of the // other arms that discover it (the suite is registered whole on the monolith DirectVulkan @@ -635,11 +635,11 @@ namespace MGITest { const std::vector top = ReadDepthFloat(0, kHeight - kHeight / 4, kWidth, kHeight / 4); EXPECT_EQ(FirstGLError(), 0u); ExpectAllDepth(top, 0.25f, "flipped resolve: the destination's top band"); - // Colour went the same way up, through the arm that could already do this. + // Color went the same way up, through the arm that could already do this. std::array colour{}; glReadPixels(kWidth / 2, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, colour.data()); EXPECT_EQ(colour, (std::array{0, 255, 0, 255})) - << "flipped resolve: colour and depth must agree about which way up the blit landed"; + << "flipped resolve: color and depth must agree about which way up the blit landed"; // THE STENCIL ASPECT, NARROW AND OFFSET ON BOTH SIDES. The copy-out moves one aspect // through a buffer one row per region, and a depth/stencil buffer<->image copy wants @@ -704,10 +704,10 @@ namespace MGITest { "the declined scale must have left the destination alone"); EXPECT_EQ(FirstGLError(), 0u) << "the session survived the decline"; - // THE SAME SCALE WITH COLOUR IN THE MASK. An erroring blit writes nothing (18.3.1), so - // the colour attachment must come through untouched too. The colour arm CAN scale a + // THE SAME SCALE WITH COLOR IN THE MASK. An erroring blit writes nothing (18.3.1), so + // the color attachment must come through untouched too. The color arm CAN scale a // multisample resolve on its own, and it runs before the depth arm - so a decline - // decided per aspect scaled and wrote the colour and then raised the error on the + // decided per aspect scaled and wrote the color and then raised the error on the // depth. The shape is decided once, before any aspect, and this is what pins it. glBindFramebuffer(GL_FRAMEBUFFER, resolved.fbo); ClearDepthStencil(GL_DEPTH24_STENCIL8, 0.5f, kPrimeStencil); @@ -725,7 +725,7 @@ namespace MGITest { std::array untouched{}; glReadPixels(1, 1, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, untouched.data()); EXPECT_EQ(untouched, (std::array{0, 0, 255, 255})) - << "the declined COLOR|DEPTH scale must not have written its colour either"; + << "the declined COLOR|DEPTH scale must not have written its color either"; ExpectAllDepth(ReadDepthFloat(0, 0, kWidth, kHeight), 0.5f, "the declined COLOR|DEPTH scale must have left the depth alone"); EXPECT_EQ(FirstGLError(), 0u) << "the session survived the combined decline"; @@ -747,7 +747,7 @@ namespace MGITest { // destination the round-2 pre-pass left to the per-aspect lambdas, on the belief that a // default draw framebuffer behind a multisample read was the resolve arm's region Fatal // whatever the shape - but that arm asks the shape question BEFORE its region check, so - // a scaled COLOR|DEPTH resolve onto the window scaled and wrote its colour through the + // a scaled COLOR|DEPTH resolve onto the window scaled and wrote its color through the // swapchain blit and then recorded INVALID_OPERATION on its depth: the partial effect // the previous leg pins for a user framebuffer, reproduced on the only other kind of // destination there is. The window is primed MAGENTA at depth 0.625 - values no other @@ -758,7 +758,7 @@ namespace MGITest { // surface, read the same priming and passed for nothing; pointing the probes at the // user framebuffer now fails on both aspects, shown once and restored. The source (red // below, green above) is blown up over the whole of the window, and three probes - a - // corner, the centre, the far corner - must all still read the priming on both + // corner, the center, the far corner - must all still read the priming on both // aspects. The harness's pbuffer default framebuffer has no other way of being looked // at than glReadPixels, which is what both probes use. { @@ -791,7 +791,7 @@ namespace MGITest { std::array window{}; glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, window.data()); EXPECT_EQ(window, (std::array{255, 0, 255, 255})) - << "the declined COLOR|DEPTH scale onto the window must not have written its colour at (" << x + << "the declined COLOR|DEPTH scale onto the window must not have written its color at (" << x << ", " << y << ")"; float depth = kDepthPoison; glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth); @@ -1278,7 +1278,7 @@ namespace MGITest { Gl().EndFrame(); } - // The PACK pixel-store parameters apply to a depth read exactly as they do to a colour + // The PACK pixel-store parameters apply to a depth read exactly as they do to a color // one, and the gap regions they create must be left alone. TEST_F(DepthStencilReadbackMatrixScenario, DepthReadbackHonoursThePackPixelStoreParameters) { if (!Ready()) return; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackScenario.cpp index 221bd041..ad27db88 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DepthStencilReadbackScenario.cpp @@ -16,7 +16,7 @@ // // That silence is what the framebuffer_blit family trips over. Every one of its cases begins by // clearing the default framebuffer's depth and stencil and reading them straight back as a -// sanity check, into a local pre-initialised to 0.2 (depth) and 50 (stencil); an untouched +// sanity check, into a local pre-initialized to 0.2 (depth) and 50 (stencil); an untouched // buffer therefore reports "expected DEPTH[0.25] but got DEPTH[0.2]" and "expected STENCIL[1] but // got STENCIL[50]" - the exact strings in the 15 Magma failures - long before any blit happens. // A test that only checked "no GL error" would pass against the broken path, so every case here @@ -24,7 +24,7 @@ // // The orientation case is the second half. This renderer stores the default framebuffer // display-side-up and converts GL rects on their way in, so the depth copy needs the same rect -// mapping and row re-ordering the colour readback got in the M-1 fix; without them a +// mapping and row re-ordering the color readback got in the M-1 fix; without them a // vertically-varying depth buffer reads back mirrored, which no full-extent uniform-value test // can see. // @@ -61,7 +61,7 @@ namespace MGITest { // Both backends now answer these reads. DirectGLES has no native ES path for // either aspect (GL_NV_read_depth / GL_NV_read_stencil are optional and absent on // both the Adreno device and llvmpipe's ES), so it stages the attachment into a - // scratch depth texture and samples it into a colour target; the assertions below + // scratch depth texture and samples it into a color target; the assertions below // are the same either way, which is the point. bool BackendReadsDepthStencil() const { return true; } @@ -80,7 +80,7 @@ namespace MGITest { // A depth buffer whose value depends on the row: bottom half `bottom`, top half `top`. // Built with a scissored clear rather than a draw so the test stays independent of - // depth-test and shader behaviour. + // depth-test and shader behavior. void ClearDepthInBands(int width, int height, float bottom, float top) { glEnable(GL_SCISSOR_TEST); glScissor(0, 0, width, height / 2); @@ -180,7 +180,7 @@ namespace MGITest { } // A depth blit INTO the default framebuffer has to convert its rect out of GL's bottom-origin - // space, exactly as the colour blit does. The colour path had that conversion and the + // space, exactly as the color blit does. The color path had that conversion and the // depth path did not, so a scissored depth blit landed in the mirrored band - which is the // whole of KHR-GL*.framebuffer_blit.scissor_blit once the readback above works well enough to // see it (before that the test died on the poison values and never reached the blit). diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DescriptorPoolGrowthScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DescriptorPoolGrowthScenario.cpp index 0e36b5da..8b0918bd 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DescriptorPoolGrowthScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DescriptorPoolGrowthScenario.cpp @@ -22,7 +22,7 @@ // Each of kDraws draws paints its own pixel of a 64x64 target and samples one of kTextures // textures, a different one from each of the previous draws' so neither the renderer's per-draw // descriptor reuse memo (four entries) nor its dynamic-offset-only rebind can let two draws share -// a set: one frame needs kDraws sets. Every pixel must hold its own draw's texture colour, on both +// a set: one frame needs kDraws sets. Every pixel must hold its own draw's texture color, on both // backends. On DirectVulkan the cases also read the pools through GetDescriptorPoolCensus - which // only the desktop build can reach, since the integration harness links the static library there // and the hidden-visibility shipping library on Android. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DoublePrecisionScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DoublePrecisionScenario.cpp index 795a69b3..d8dcee79 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DoublePrecisionScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DoublePrecisionScenario.cpp @@ -262,7 +262,7 @@ void main() { } // The block's contents, at the offsets the standard puts them. Padding stays zero, which - // is what makes a byte-for-byte comparison against the (zero-initialised) output buffer + // is what makes a byte-for-byte comparison against the (zero-initialized) output buffer // catch a member that landed somewhere it should not have. std::vector MakeBlockContents(const BlockLayout& layout) { std::vector bytes(static_cast(layout.size), 0); @@ -441,7 +441,7 @@ void main() { const GLint scalar = glGetUniformLocation(m_program, "uScalar"); ASSERT_GE(scalar, 0); // 0.1 has no exact float (or double) representation, so this only passes if the - // value really travelled through the demoted slot rather than being read out of + // value really traveled through the demoted slot rather than being read out of // some other four bytes. glUniform1d(scalar, 0.1); glUseProgram(0); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DrawParametersScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DrawParametersScenario.cpp index 4bbdb0ac..7c0f4308 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DrawParametersScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DrawParametersScenario.cpp @@ -24,7 +24,7 @@ // gl_BaseInstance read an unbound storage buffer on a plain glDrawArrays. // // The shader paints the three values, so a draw that carries the wrong ones -// paints the wrong colour rather than merely disagreeing with an expectation +// paints the wrong color rather than merely disagreeing with an expectation // somewhere. The framebuffer is cleared to WHITE and no case expects 255 in any // channel, so "the draw did not happen" can never be mistaken for a pass. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DsaUpdateKeepsTheBoundUnitScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DsaUpdateKeepsTheBoundUnitScenario.cpp index 0ac2a0e0..a8b4e24a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DsaUpdateKeepsTheBoundUnitScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DsaUpdateKeepsTheBoundUnitScenario.cpp @@ -54,7 +54,7 @@ void main() { )"; // texelFetch at the texture's own last texel: a texture whose shape moved to B's would - // fetch a different texel, and one whose contents moved would fetch B's colour. + // fetch a different texel, and one whose contents moved would fetch B's color. constexpr const char* kFetchFS = R"(#version 330 core uniform sampler2D uTex; out vec4 oColor; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DualBlockScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DualBlockScenario.cpp index edddc6b3..722b1f14 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DualBlockScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DualBlockScenario.cpp @@ -70,7 +70,7 @@ namespace MGITest { EXPECT_NE(before.serverIdentity, nullptr) << "dual-block control: the server block's identity was never set (CONTRACT-P5E §3.2's " "server-owned SetIdentity) - the backend's identity-keyed memo caches read nullptr " - "as a hit on their zero-initialised slot"; + "as a hit on their zero-initialized slot"; // One client verb boundary, driven directly so no draw reaches the server: the CLIENT // block's serial must move and the SERVER block's must not. Under a shared block the second diff --git a/MobileGL/MG_IntegrationTest/Scenarios/DualSourceBlendScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/DualSourceBlendScenario.cpp index 7b39b737..38ec6ff6 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/DualSourceBlendScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/DualSourceBlendScenario.cpp @@ -176,10 +176,10 @@ void main() // The whole point of the scenario: this sequence used to be a process kill on any device // without the capability, and it has to be a picture either way. // - // dst is black, src0 is white and src1 is mid-grey, with SRC1_COLOR / ONE_MINUS_SRC1_COLOR. + // dst is black, src0 is white and src1 is mid-gray, with SRC1_COLOR / ONE_MINUS_SRC1_COLOR. // blended = 1.0 * 0.5 + 0.0 * 0.5 = 0.5 -> ~128 // declined = 1.0 -> 255 - // Anything else means the factors were mistranslated rather than either honoured or declined. + // Anything else means the factors were mistranslated rather than either honored or declined. TEST_F(DualSourceBlendScenario, DualSourceBlendDrawProducesOneOfTheTwoDefinedResults) { if (!Ready()) GTEST_SKIP(); if (const std::string reason = WhyTheProgramCannotRun(); !reason.empty()) GTEST_SKIP() << reason; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/F1WireScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/F1WireScenario.cpp index 1857d129..0b1e9d5a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/F1WireScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/F1WireScenario.cpp @@ -577,12 +577,12 @@ void main() { color = vec4(value, 0.25, 0.75, 1.0); } // MGPipe: Fatal{UnmigratedVerb, "Magma:mipmap-shader-format-or-shape"} // deterministically, under both run-ahead and lockstep, while the monolith arm passed and the // host lane stayed green. It stayed green because lavapipe reports BLIT_SRC|BLIT_DST for every - // colour format this scenario can create: `nativeBlit` is always true here, so NEITHER shader + // color format this scenario can create: `nativeBlit` is always true here, so NEITHER shader // arm of GenerateWireMipmap has ever executed on the gate machine. A refusal no host lane can // reach is a refusal that ships. // // MGITEST_MAGMA_FORCE_SHADER_MIPMAP is what makes them reachable, and it selects which one: - // 1 - drop the native blit only. The destination level is still a colour attachment, so the + // 1 - drop the native blit only. The destination level is still a color attachment, so the // pass renders straight into it (the arm an Adreno takes for a format without BLIT_DST). // 2 - also treat the destination as not attachable. The pass renders into owned scratch and // copies the mip in (the arm it takes for a texture whose image never got @@ -603,8 +603,8 @@ void main() { color = vec4(value, 0.25, 0.75, 1.0); } glDisable(GL_SCISSOR_TEST); glClearColor(0.75f, 0.25f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - // Two different halves, not one flat colour: a pass that loses GL's row order averages to - // the same number everywhere and a single-colour assertion would call that correct. + // Two different halves, not one flat color: a pass that loses GL's row order averages to + // the same number everywhere and a single-color assertion would call that correct. glEnable(GL_SCISSOR_TEST); glScissor(0, 0, 8, 4); glClearColor(0.25f, 0.75f, 0.5f, 1.0f); @@ -614,7 +614,7 @@ void main() { color = vec4(value, 0.25, 0.75, 1.0); } glGenerateMipmap(GL_TEXTURE_2D); ASSERT_GT(PeekSplitRuntime().emitSeq, before) << "F1.ShaderMip.wire"; // Level one is 4x4, and each of its rows averages two source rows from ONE half - the - // boundary never falls inside a destination texel, so the two colours survive unmixed. + // boundary never falls inside a destination texel, so the two colors survive unmixed. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1); ASSERT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GLenum(GL_FRAMEBUFFER_COMPLETE)); GLubyte rows[4][4]{}; @@ -658,7 +658,7 @@ void main() { color = vec4(value, 0.25, 0.75, 1.0); } // TWO HALVES AND A BAND THAT IS NOT ASSERTED. The generated level is read back through a real // sampled attachment, so a flat fill would prove nothing: the source is split at its middle // row instead. The ported filter takes a 2x2 box at ivec2(texCoord * srcTexelSize), which - // lands half a texel off the destination centre - the monolith's own arithmetic, kept + // lands half a texel off the destination center - the monolith's own arithmetic, kept // deliberately (§3.2 retires a refusal by matching that arm, defects included). Under either // reading of that half texel, destination rows 0..2 come only from the lower half and rows // 4..7 only from the upper half; row 3 is the straddle and is the one row this case does not @@ -778,7 +778,7 @@ void main() { color = vec4(value, 0.25, 0.75, 1.0); } // P8-F: `Magma:mipmap-shader-format-or-shape` IS A NAMED DECLINE ON THE WIRE ARM NOW, which is // the monolith arm's answer for a chain it cannot build (VulkanRenderer.cpp's GenerateMipmap // declines a format without blit support and leaves the chain unwritten). It used to end the - // session. A 3D texture is a shape neither wire shader arm takes (the colour pass samples a + // session. A 3D texture is a shape neither wire shader arm takes (the color pass samples a // sampler2D), so with the native blit forced off (MGITEST_MAGMA_FORCE_SHADER_MIPMAP) it is what // reaches the refusal on this host - lavapipe blits a 3D RGBA8 chain natively otherwise. // @@ -1087,7 +1087,7 @@ void main() { imageStore(destination, ivec2(gl_GlobalInvocationID.xy), vec4(0.0, glDeleteTextures(1, &root); } - // Historical case name retained for the registered test catalogue. The old P7 + // Historical case name retained for the registered test catalog. The old P7 // refusal is retired: this case now requires the VBO draw's actual green pixels. TEST_F(F1WireScenario, EnabledVertexBufferDrawKeepsNamedP7Fatal) { if (!Ready()) return; @@ -1138,14 +1138,14 @@ void main() { color = vec4(0.0, 1.0, 0.0, 1.0); } if (!Ready()) return; Attach(GL_RGBA8); const char* fragment = R"(#version 430 core -layout(std140, binding=3) uniform Colour { vec4 value; }; +layout(std140, binding=3) uniform Color { vec4 value; }; layout(location=0) out vec4 color; void main() { color = value; } )"; const GLuint program = BuildWireProgram({{GL_VERTEX_SHADER, kWireVertexIdTriangle}, {GL_FRAGMENT_SHADER, fragment}}); ASSERT_NE(program, 0u); - const GLuint block = glGetUniformBlockIndex(program, "Colour"); + const GLuint block = glGetUniformBlockIndex(program, "Color"); ASSERT_NE(block, GLuint(GL_INVALID_INDEX)); glUniformBlockBinding(program, block, 3); GLint alignment = 0; @@ -1706,7 +1706,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } glClearColor(1, 0, 1, 1); glClear(GL_COLOR_BUFFER_BIT); glViewport(2, 1, 5, 3); - // Copy into the centre half with BOTH destination axes reversed. Scissor + // Copy into the center half with BOTH destination axes reversed. Scissor // keeps only its left half, so a plain unclipped vkCmdBlitImage is incorrect. glScissor(width / 4, height / 4, width / 4, height / 2); glEnable(GL_SCISSOR_TEST); @@ -1739,7 +1739,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } // four rotations declines by name. // // THE SOURCE IS A 3D TEXTURE SLICE, which is ordinary defined GL (a layer of a 3D texture is a - // legal colour attachment) and is exactly the shape the shader pass cannot sample. The same case + // legal color attachment) and is exactly the shape the shader pass cannot sample. The same case // runs twice on each arm: plain, taking the identity fall-through, and under // MGITEST_MAGMA_FORCE_DEFAULT_BLIT_SCRATCH, taking the rotated arm's scratch path on an identity // surface - where it must produce THE SAME PIXELS. That equality is what makes the scratch arm @@ -1771,7 +1771,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } glClear(GL_COLOR_BUFFER_BIT); } glDisable(GL_SCISSOR_TEST); - // The OTHER slice gets one flat colour that appears in no quadrant. + // The OTHER slice gets one flat color that appears in no quadrant. glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, volume, 0, 0); glClearColor(0, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT); @@ -1805,10 +1805,10 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } } namespace { - // An 8x4 RGBA8 colour renderbuffer at `samples`, bottom half red and top half green in GL row - // order. TWO HALVES AND NOT ONE COLOUR, for the reason the shader-mip case gives: a pass that + // An 8x4 RGBA8 color renderbuffer at `samples`, bottom half red and top half green in GL row + // order. TWO HALVES AND NOT ONE COLOR, for the reason the shader-mip case gives: a pass that // loses GL's row order averages a flat fill back to the same number everywhere and a - // single-colour assertion calls that correct. Returns false when this driver cannot host the + // single-color assertion calls that correct. Returns false when this driver cannot host the // attachment, which is a skip and not a failure. bool MakeMultisampleHalvesFbo(int samples, GLuint& fbo, GLuint& renderbuffer) { glGenFramebuffers(1, &fbo); @@ -1831,7 +1831,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } return true; } - // A single-sample RGBA8 destination of the given size, cleared to a colour that appears in no + // A single-sample RGBA8 destination of the given size, cleared to a color that appears in no // assertion below - so "the blit did nothing" and "the blit landed the wrong band" read // differently from each other. void MakeSingleSampleTarget(int width, int height, const GLfloat (&clear)[4], GLuint& fbo, GLuint& tex) { @@ -1849,7 +1849,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } // P7 wave 2-B2, CONTRACT-P7 §3.2: `multisample-blit-shape@P7` RETIRES. // // vkCmdResolveImage carries ONE extent and one offset per side. It can neither scale nor flip, - // so the wire arm refused every multisample colour blit whose destination rectangle was a + // so the wire arm refused every multisample color blit whose destination rectangle was a // different size from its source - which glBlitFramebuffer names, and which the MONOLITH arm // already reaches by the route this package gives the wire arm (VulkanRenderer.cpp's // `regionWasTransformed` branch: resolve into a scratch at raw offsets, then blit the scratch). @@ -1858,12 +1858,12 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } // // THE SCALE AND THE FLIP IN ONE CASE, over the same source, because they fail differently: a // blit that dropped the scale lands a 8x4 band in a 4x2 attachment (and the driver refuses the - // command), while one that dropped the flip returns the right two colours in the wrong order. + // command), while one that dropped the flip returns the right two colors in the wrong order. // The second blit's expectation is the first's, rows swapped, so neither can pass the other's // assertion. // // Red once (executed, reverted): restore the two `width != |dx1-dx0|` clauses in - // WireFramebuffer.cpp's colour resolve arm and both blits die as + // WireFramebuffer.cpp's color resolve arm and both blits die as // Fatal{UnmigratedVerb, "Magma:multisample-resolve-region"}. TEST_F(F1WireScenario, MultisampleColorBlitScalesAndFlipsThroughTheResolveScratch) { if (!Ready()) return; @@ -1878,7 +1878,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } // Half the source in each axis: every destination texel is the resolve of a 2x2 source box // that lies wholly inside ONE half, so the boundary never falls inside a destination texel - // and the two colours cannot mix. + // and the two colors cannot mix. constexpr GLfloat kBlue[4]{0, 0, 1, 1}; GLuint dstFbo = 0, dstTexture = 0; MakeSingleSampleTarget(4, 2, kBlue, dstFbo, dstTexture); @@ -1965,7 +1965,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } } while (glGetError() != GLenum(GL_NO_ERROR)) {} glDisable(GL_SCISSOR_TEST); - glClearColor(1, 0, 1, 1); // magenta: the colour the declined blit must leave behind + glClearColor(1, 0, 1, 1); // magenta: the color the declined blit must leave behind glClear(GL_COLOR_BUFFER_BIT); ASSERT_EQ(FirstGLError(), GLenum(GL_NO_ERROR)) << "F1.MsBlitDecline.setup"; @@ -1985,7 +1985,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } // decline records its error where the blit is PERFORMED - the server's apply thread - and // that error reaches this client's queue with a later reply, not with the blit call. Without // the round trip the check below reads GL_NO_ERROR and the INVALID_OPERATION surfaces at - // whatever the next synchronising call happens to be, which is how it first showed up: + // whatever the next synchronizing call happens to be, which is how it first showed up: // attached to the resolve twenty lines down, a call that is not wrong about anything. glFinish(); EXPECT_EQ(FirstGLError(), GLenum(GL_INVALID_OPERATION)) @@ -2061,7 +2061,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } } while (glGetError() != GLenum(GL_NO_ERROR)) {} glDisable(GL_SCISSOR_TEST); - glClearColor(1, 0, 1, 1); // magenta: the colour the declined blit must leave behind + glClearColor(1, 0, 1, 1); // magenta: the color the declined blit must leave behind glClear(GL_COLOR_BUFFER_BIT); ASSERT_EQ(FirstGLError(), GLenum(GL_NO_ERROR)) << "F1.MsAspectDecline.setup"; @@ -2276,7 +2276,7 @@ void main() { color = vec4(0.5, 0.5, 0.5, 1.0); } // environment) carries MGITEST_MAGMA_FORCE_STALE_BUFFER_SERIAL=1, which forces the serial half // of the busy predicate to answer "idle" - the state the unsound completed-serial floor put the // wire arm into on the device. With the serial half forced to lie, only the submission-fence - // half can still order the copy, so the entry pins that DEFENCE term. The guarantee is the + // half can still order the copy, so the entry pins that DEFENSE term. The guarantee is the // floor (VulkanRenderer::OnSubmitsCompletedUpTo), which the knob bypasses; its lane is the // OpenRA split retrace's "MGWIRE-FLOOR unsound-serial-complete" red condition. TEST_F(F1WireScenario, StreamedBufferSubDataBeforeEachDrawIsOrdered) { @@ -2296,8 +2296,8 @@ void main() { fragColor = vColor; } )"}}); ASSERT_NE(program, 0u); - // One vertical bar per batch, each in its own two-pixel column and its own colour, so a - // draw that read another batch's bytes lands in the wrong column AND the wrong colour. + // One vertical bar per batch, each in its own two-pixel column and its own color, so a + // draw that read another batch's bytes lands in the wrong column AND the wrong color. constexpr GLfloat kColors[kBatches][4] = {{1, 0, 0, 1}, {0, 1, 0, 1}, {0, 0, 1, 1}, {1, 1, 0, 1}}; const auto batchVertices = [&](int batch) { const GLfloat x0 = -1.0f + static_cast(batch) * 0.5f; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/FormatlessImageBakeScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/FormatlessImageBakeScenario.cpp index 44de0507..aa39cd9b 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/FormatlessImageBakeScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/FormatlessImageBakeScenario.cpp @@ -17,7 +17,7 @@ // // The two routes had different arming. The declared route armed the widening on the format // alone; the baked route armed it only when the driver lacked GL_NV_image_formats. That reads -// like an optimisation and is not one: SPIRV-Cross throws for its is_desktop_only_format set the +// like an optimization and is not one: SPIRV-Cross throws for its is_desktop_only_format set the // moment it targets ESSL, whatever the driver would have accepted, so on a driver that HAS the // extension the shader half of the widening stayed switched off while TextureImpl's storage/bind // half - which keys on SpirvCrossCanPrintEsslImageFormat, not on the driver bit - still ran. The diff --git a/MobileGL/MG_IntegrationTest/Scenarios/FragmentOutputArrayIndexScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/FragmentOutputArrayIndexScenario.cpp index d7def66d..2c879df3 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/FragmentOutputArrayIndexScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/FragmentOutputArrayIndexScenario.cpp @@ -128,7 +128,7 @@ void main() { ScenarioTest::TearDown(); } - // Clears both attachments to a colour no shader below writes, so an attachment that + // Clears both attachments to a color no shader below writes, so an attachment that // was never written reads back as the sentinel rather than as a plausible value. void ClearToSentinel() { glClearColor(0.0f, 0.0f, 1.0f, 1.0f); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/GenerateMipmapServerScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/GenerateMipmapServerScenario.cpp index 15a7657b..bfe53431 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/GenerateMipmapServerScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/GenerateMipmapServerScenario.cpp @@ -21,7 +21,7 @@ // // EVERY CASE CHECKS THE GL ANSWER BY SAMPLING. The base level is split into two halves (bottom // rows A, top rows B) so a generation that loses the row order, or reads another level, cannot -// average to the right colour. Each generated level is read back through texelFetch into an RGBA8 +// average to the right color. Each generated level is read back through texelFetch into an RGBA8 // target, and the levels outside the window are checked unchanged (or still undefined). // // ARMS. Both backends, monolith and Split / Spawn / Tcp; Magma is the control. The forced-CPU arm @@ -45,7 +45,7 @@ // ignoring BASE_LEVEL and MAX_LEVEL, and the storage grow before them defines levels past // MAX_LEVEL (DirectGLES.cpp GenerateColorTexture2DMipmap / GenerateDepthTexture2DMipmap / // EnsureGenerateMipmapStorageAllocated); -// M3 Magma: a colour format without BLIT_SRC|BLIT_DST (R11F_G11F_B10F on lavapipe) is skipped +// M3 Magma: a color format without BLIT_SRC|BLIT_DST (R11F_G11F_B10F on lavapipe) is skipped // with a warning and its levels stay undefined texels - the monolith has no shader arm, // which the wire arm has had since P7 (VulkanRenderer.cpp GenerateMipmap). @@ -484,8 +484,8 @@ void main() { o_color = gl_FragCoord.y < u_split ? u_bottom : u_top; } if (status != GL_FRAMEBUFFER_COMPLETE) { glBindFramebuffer(GL_FRAMEBUFFER, 0); FirstGLError(); - GTEST_SKIP() << format.name << " is not colour-renderable on " << Gl().BackendName() - << " (status 0x" << std::hex << status << ")"; + GTEST_SKIP() << format.name << " is not color-renderable on " << Gl().BackendName() << " (status 0x" + << std::hex << status << ")"; } glViewport(0, 0, kEdge, kEdge); glUseProgram(m_paintProgram); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/GeometryDrawModeScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/GeometryDrawModeScenario.cpp index c6043267..16e4da0b 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/GeometryDrawModeScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/GeometryDrawModeScenario.cpp @@ -242,12 +242,12 @@ void main() glDrawTransformFeedbackInstanced(GL_LINES, feedback, 1); EXPECT_EQ(glGetError(), static_cast(GL_INVALID_OPERATION)) - << "glDrawTransformFeedbackInstanced must honour the geometry input primitive"; + << "glDrawTransformFeedbackInstanced must honor the geometry input primitive"; DrainErrors(); glDrawTransformFeedbackStreamInstanced(GL_LINES, feedback, 0, 1); EXPECT_EQ(glGetError(), static_cast(GL_INVALID_OPERATION)) - << "glDrawTransformFeedbackStreamInstanced must honour the geometry input primitive"; + << "glDrawTransformFeedbackStreamInstanced must honor the geometry input primitive"; DrainErrors(); // The compatible mode replays the captured span with no error at all, which is what diff --git a/MobileGL/MG_IntegrationTest/Scenarios/Glsl420DeclarationScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/Glsl420DeclarationScenario.cpp index fa6ca9c9..6e846057 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/Glsl420DeclarationScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/Glsl420DeclarationScenario.cpp @@ -181,7 +181,7 @@ out vec4 o_color; void main() { o_color = vec4(0.0, 1.0, 0.0, 1.0); } )"; - // The colour index spelled out at its default value. Says nothing that + // The color index spelled out at its default value. Says nothing that // `layout(location = 0)` alone does not, and must therefore cost nothing. constexpr const char* kExplicitColorIndexFS = R"(#version 420 core layout(location = 0, index = 0) out vec4 o_color; @@ -215,7 +215,7 @@ void main() { o_color = vec4(0.0, 1.0, 0.0, 1.0); } return program; } - // One 1x1 RGBA8 texture per element, each a colour whose channels are exactly 0 or + // One 1x1 RGBA8 texture per element, each a color whose channels are exactly 0 or // 255 so the shader's == comparisons are exact. void MakeElementTextures(const std::uint8_t colors[kElements][4]) { m_textures.assign(kElements, 0); @@ -242,7 +242,7 @@ void main() { o_color = vec4(0.0, 1.0, 0.0, 1.0); } glBindBuffer(GL_UNIFORM_BUFFER, 0); } - // Draws the full-screen quad and hands back the centre pixel. + // Draws the full-screen quad and hands back the center pixel. Rgba8 DrawAndRead(GLuint program) { HeadlessGL& gl = Gl(); if (m_vao == 0) glGenVertexArrays(1, &m_vao); @@ -340,7 +340,7 @@ void main() { o_color = vec4(0.0, 1.0, 0.0, 1.0); } // // Deliberately weak on the pixels for that reason: what is asserted on every backend is that // the program builds, the draw raises no GL error, and the process survives. Where the - // descriptors do resolve, the colours are checked too. + // descriptors do resolve, the colors are checked too. TEST_F(Glsl420DeclarationScenario, AnArrayOfSamplerArraysIsHonouredOrDeclinedCleanly) { if (!Ready()) return; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/GpuWrittenDrawInputScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/GpuWrittenDrawInputScenario.cpp index 9f24ad52..8d79c2ff 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/GpuWrittenDrawInputScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/GpuWrittenDrawInputScenario.cpp @@ -194,7 +194,7 @@ void main() { ScenarioTest::SetUp(); if (!Ready()) return; m_target = MakeColorFbo(kSurface, kSurface); - ASSERT_NE(m_target.fbo, 0u) << "the 64x64 colour target did not build"; + ASSERT_NE(m_target.fbo, 0u) << "the 64x64 color target did not build"; glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); glDisable(GL_DEPTH_TEST); @@ -410,7 +410,7 @@ void main() { << what << ": the gap is covered, so the restart at index 7 was dropped"; } - // Left and right half of the halves scene, sampled at their centres. + // Left and right half of the halves scene, sampled at their centers. static Rgba8 Half(const Image& image, int half) { return image.At(kSurface * (1 + 2 * half) / 4, kSurface / 2); } diff --git a/MobileGL/MG_IntegrationTest/Scenarios/GuiBatchScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/GuiBatchScenario.cpp index 6018d22d..a380f89e 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/GuiBatchScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/GuiBatchScenario.cpp @@ -28,8 +28,8 @@ // quad came out degenerate. Items were unaffected because item geometry DOES come from cached // meshes, which is what made the bug look like "only the backgrounds disappear". // -// The assertions are whole-region, not centre-pixel: a quad that survives with three stale -// vertices still paints its centre. +// The assertions are whole-region, not center-pixel: a quad that survives with three stale +// vertices still paints its center. // // Reproduces on DirectVulkan only. DirectGLES forwards the unbound binding to the GLES driver, // which does what GL says, so it is the control - every test here must stay green on both. @@ -421,7 +421,7 @@ void main() { glMapNamedBufferRange(m_inVaryings[b], 0, 4 * (GLsizeiptr)sizeof(VaryingData), persistent); } - // Two SharingData entries: builder 0 lands left of centre, builder 1 right. + // Two SharingData entries: builder 0 lands left of center, builder 1 right. float sharing[56] = {}; const float tx[2] = {-0.9f, 0.1f}; for (int b = 0; b < 2; ++b) { @@ -710,7 +710,7 @@ void main() { // an unbound SSBO did. The mod reaches this with its INDIRECT draw method, whose culling // shaders carry a counter the BASEVERTEX default never binds. // - // The counter is INCREMENTED, not merely declared: an unreferenced one is optimised out + // The counter is INCREMENTED, not merely declared: an unreferenced one is optimized out // before it ever reaches a descriptor, so a shader that only declares it proves nothing. constexpr const char* kCounterComputeSource = R"(#version 430 core layout(local_size_x = 1) in; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/HandleRecycleScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/HandleRecycleScenario.cpp index 9ae11d89..40b47c42 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/HandleRecycleScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/HandleRecycleScenario.cpp @@ -160,7 +160,7 @@ namespace MGITest { return Arm::Legacy; } - // Whether the lane named an arm this file knows. A value that is set but unrecognised is a + // Whether the lane named an arm this file knows. A value that is set but unrecognized is a // FAILURE (SetUp below), never a quiet fall-through to Legacy: a typo in a lane's // MGITEST_HANDLE_ARM would otherwise downgrade that lane's Handles or AbaControl assertion // to the Legacy one, which passes - a lane reporting green for an arm it never ran. Same @@ -299,7 +299,7 @@ namespace MGITest { // {slot, gen}"; the P3a one answers it for the BUFFER. P4a re-keys six more object classes // - texture, renderbuffer, framebuffer, sampler CSO, sampler view and shader CSO - and // their four subsystem bits (kMGPipeSubsystem{Framebuffer,TextureResources,Samplers, - // Programs}, MGPipe.h) are what a backend has to name to honour MOBILEGL_PIPE_PUSH's + // Programs}, MGPipe.h) are what a backend has to name to honor MOBILEGL_PIPE_PUSH's // default mask. A P4a case that read either older marker would report the Handles arm as // armed on a tree where nothing about a texture is keyed on a handle - green for a re-key // that does not exist, which is the one outcome this file exists to prevent. Set by @@ -384,8 +384,8 @@ void main() { oColor = texture(uTex, vUv); } float r, g, b; }; - // A full-viewport quad in one colour. Both buffers are the SAME SIZE and the SAME - // LAYOUT: only the colour bytes differ, which is what makes a content hash over the + // A full-viewport quad in one color. Both buffers are the SAME SIZE and the SAME + // LAYOUT: only the color bytes differ, which is what makes a content hash over the // vertex-input CONFIGURATION identical between them. std::vector Quad(float r, float g, float b) { return { @@ -443,7 +443,7 @@ void main() { oColor = texture(uTex, vUv); } if (!ArmNameIsRecognised()) { const char* raw = std::getenv(kArmMarker); FAIL() << "unknown " << kArmMarker << " value '" << (raw != nullptr ? raw : "") - << "': the arms are handles / legacy / aba. Reading an unrecognised name " + << "': the arms are handles / legacy / aba. Reading an unrecognized name " "as Legacy would make this lane assert the pre-re-key guards while " "claiming to test something else, and it would pass."; } @@ -583,7 +583,7 @@ void main() { oColor = texture(uTex, vUv); } return wired; } - // A VBO holding one solid-colour quad. + // A VBO holding one solid-color quad. GLuint MakeQuadBuffer(float r, float g, float b) { const std::vector vertices = Quad(r, g, b); GLuint buffer = 0; @@ -606,7 +606,7 @@ void main() { oColor = texture(uTex, vUv); } reinterpret_cast(offsetof(Vertex, r))); } - // The same quad, split across TWO buffers - positions in one, colours in the other, + // The same quad, split across TWO buffers - positions in one, colors in the other, // one MGPVertexBuffer entry each. What travels in a P3a `set_vertex_buffers` is the // per-binding BUFFER IDENTITY (D-H3: Res, Offset 0, the resolved stride and // divisor); the formats live in the vertex-elements blob and are byte-identical @@ -653,7 +653,7 @@ void main() { oColor = texture(uTex, vUv); } return image; } - // A 2x2 RGBA8 texture of one colour, with the sampling parameters spelled the same + // A 2x2 RGBA8 texture of one color, with the sampling parameters spelled the same // way both times so a parameter-shadow key matches too. GLuint MakeSolidTexture(std::uint8_t r, std::uint8_t g, std::uint8_t b) { const std::uint8_t texels[16] = {r, g, b, 255, r, g, b, 255, r, g, b, 255, r, g, b, 255}; @@ -907,7 +907,7 @@ void main() { oColor = texture(uTex, vUv); } // manager-wide slice-epoch counter, and a moved counter sends the resolved-bindings // memo into a revalidation that re-reads every binding from the live VAO. That gate is // not an identity gate and it is not what this case is about, so both buffers are - // realised up front and the ABA window contains no buffer traffic at all. + // realized up front and the ABA window contains no buffer traffic at all. const GLuint redBuffer = MakeQuadBuffer(1.0f, 0.0f, 0.0f); const GLuint greenBuffer = MakeQuadBuffer(0.0f, 1.0f, 0.0f); @@ -987,10 +987,10 @@ void main() { oColor = texture(uTex, vUv); } // splits that record in two: the formats travel once per configuration, in // `create_vertex_elements`' blob, and the per-binding BUFFER IDENTITIES travel in // `set_vertex_buffers` (D-G2, D-H3). So the replacement here shares its predecessor's - // POSITION buffer and differs in the COLOUR buffer alone: the elements blob is + // POSITION buffer and differs in the COLOR buffer alone: the elements blob is // byte-identical between the two VAOs, exactly one entry of the buffer set moved, and // a replacement that inherited the dead VAO's set draws its own geometry in the dead - // VAO's colour. A single-buffer window cannot produce that picture. + // VAO's color. A single-buffer window cannot produce that picture. // // A SEPARATE CASE RATHER THAN A SECOND WINDOW IN THE ONE ABOVE, and the reason is // measured. gtest_discover_tests registers one ctest entry per case, so a case is a @@ -1015,14 +1015,14 @@ void main() { oColor = texture(uTex, vUv); } const GLuint redColorBuffer = MakeColorBuffer(1.0f, 0.0f, 0.0f); const GLuint greenColorBuffer = MakeColorBuffer(0.0f, 1.0f, 0.0f); - // Same rule as the case above: every buffer is realised and DRAWN WITH before the + // Same rule as the case above: every buffer is realized and DRAWN WITH before the // window, so the window contains no buffer traffic and the slice-epoch gate - which // is not an identity gate - is not what decides the verdict. GLuint splitPrimerVao = 0; glGenVertexArrays(1, &splitPrimerVao); ConfigureSplitQuadVao(splitPrimerVao, positionBuffer, greenColorBuffer); const Image splitPrimed = DrawQuadAndRead(splitPrimerVao); - ExpectWholeViewportIs(splitPrimed, "green", "priming the split replacement's colour buffer"); + ExpectWholeViewportIs(splitPrimed, "green", "priming the split replacement's color buffer"); GLuint splitRedVao = 0; glGenVertexArrays(1, &splitRedVao); @@ -1102,7 +1102,7 @@ void main() { oColor = texture(uTex, vUv); } SkipUnlessTheResourceHandlePathIsAssertableHere(); if (IsSkipped()) return; - // Both survivors are realised and drawn with before the window, for the reason the + // Both survivors are realized and drawn with before the window, for the reason the // vertex-array case gives: a buffer touched for the first time moves the manager-wide // slice epoch, and that gate is not an identity gate. const GLuint parkingBuffer = MakeQuadBuffer(0.0f, 0.0f, 1.0f); @@ -1166,7 +1166,7 @@ void main() { oColor = texture(uTex, vUv); } // them, VkBufferManager's manager-wide slice epoch, MOVES when the replacement is // created and the replacement is created INSIDE this window by construction (a // buffer ABA cannot be built without creating a buffer in it). It does not: on the - // contract tree both AbaControl lanes read the dead buffer's colour over 100% of + // contract tree both AbaControl lanes read the dead buffer's color over 100% of // the viewport ("first offender at (2,2) is red rgba(255,0,0,255)"). So the control // reaches the buffer path too, and the line below records what was observed on // EVERY arm, whether or not the case passes. @@ -1368,12 +1368,12 @@ void main() { oColor = texture(uTex, vUv); } << " dead texels are not red)."; } else { EXPECT_EQ(replacementIsNotGreen, 0) - << "the replacement framebuffer's own attachment is not the colour it was " + << "the replacement framebuffer's own attachment is not the color it was " "cleared to, so the clear reached a framebuffer this one only shares an " "address with (first texel rgba=" << static_cast(replacementTexels[0]) << "," << static_cast(replacementTexels[1]) << "," << static_cast(replacementTexels[2]) << "," << static_cast(replacementTexels[3]) << ")"; - EXPECT_EQ(deadIsNotRed, 0) << "the DEAD framebuffer's attachment changed colour, so the replacement's " + EXPECT_EQ(deadIsNotRed, 0) << "the DEAD framebuffer's attachment changed color, so the replacement's " "clear reached the framebuffer it only shares a name with"; } @@ -1521,7 +1521,7 @@ void main() { oColor = texture(uTex, vUv); } // // Two kinds carry a wrinkle the others do not: // * FRAMEBUFFER has a handle and NO wire lifetime (D-I2). There is no framebuffer row in - // the call catalogue at all: the applier learns of one only through + // the call catalog at all: the applier learns of one only through // set_framebuffer_state keyed by Fbo, and the death helper does the notice and the // free and emits nothing. The allocator is therefore the ONLY observable of a // framebuffer's lifetime, which is what the leak case reads. @@ -1538,7 +1538,7 @@ void main() { oColor = texture(uTex, vUv); } // address-keyed registry the texture uses, and P4a re-keys it on {slot, gen}. // // The replacement is deliberately a DIFFERENT SIZE, because a renderbuffer cannot be - // sampled and so has no colour of its own to inherit: what a stale twin gets wrong is + // sampled and so has no color of its own to inherit: what a stale twin gets wrong is // the STORAGE, and the storage's extent is the one property a readback can see. 8x8 // green against a dead 4x4 red: fresh reads green everywhere, and a replacement that // inherited the dead 4x4 driver renderbuffer either leaves the outer ring unwritten or @@ -1632,13 +1632,13 @@ void main() { oColor = texture(uTex, vUv); } // ------------------------------------------------------------------------------------ // 5. The sampler object (SamplerCso). P4a content-addresses sampler CSOs at capacity 256 - // and hashes them field-wise over a canonical zero-initialised copy (D-F1), so two + // and hashes them field-wise over a canonical zero-initialized copy (D-F1), so two // sampler objects with identical parameters are ONE CSO by design - which is why the // ABA here is built out of two samplers whose parameters DIFFER. // - // The observable is the BORDER COLOUR, sampled at a constant UV outside [0,1] with + // The observable is the BORDER COLOR, sampled at a constant UV outside [0,1] with // GL_CLAMP_TO_BORDER, so every fragment reads the border and the whole viewport is one - // colour. That is deliberate: the border colour is the sampler parameter with the + // color. That is deliberate: the border color is the sampler parameter with the // fewest other paths to the driver (it is not in the texture's own parameter set the // way a filter effectively is), and borderColorForm is the very field G7's second // negative control drops. @@ -1655,7 +1655,7 @@ void main() { oColor = texture(uTex, vUv); } glGenVertexArrays(1, &vao); ConfigureQuadVao(vao, buffer); // The texture is BLUE and is never what the case reads: every fragment samples outside - // [0,1], so what comes back is the sampler's border colour and nothing else. + // [0,1], so what comes back is the sampler's border color and nothing else. const GLuint texture = MakeSolidTexture(0, 0, 255); const auto makeBorderSampler = [](float r, float g, float b) { @@ -1669,7 +1669,7 @@ void main() { oColor = texture(uTex, vUv); } glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, border); return sampler; }; - // Sampled at a constant UV well outside [0,1]: one colour for the whole viewport. + // Sampled at a constant UV well outside [0,1]: one color for the whole viewport. static const char* kBorderFS = R"(#version 330 core uniform sampler2D uTex; out vec4 oColor; @@ -1835,7 +1835,7 @@ void main() { oColor = texture(uTex, vec2(4.0, 4.0)); } // ProgramObject; P4a re-keys it on the shader CSO's {slot, gen} and gives the program a // create_shader_state / delete_shader_state lifetime of its own. // - // A program's colour is BAKED INTO ITS SOURCE here rather than passed as a uniform, so + // A program's color is BAKED INTO ITS SOURCE here rather than passed as a uniform, so // "the draw used the dead program" is the only thing the pixels can mean: a uniform // would be re-set on the replacement and would hide exactly the inheritance the case is // about. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ImageBindableRemintScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ImageBindableRemintScenario.cpp index 0bd59a93..ed216309 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ImageBindableRemintScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ImageBindableRemintScenario.cpp @@ -202,7 +202,7 @@ void main() { o_color = texelFetch(u_tex, ivec2(gl_FragCoord.xy) % 4, 0); } EXPECT_EQ(linked, GL_TRUE) << "the copy program did not link"; glUseProgram(program); // P11 M: A BARRIER THE SPEC DOES NOT ASK FOR, pinned for the reason - // TextureRemintPullScenario's twin gives (ID-P9-11, DEBTS "待归因"): on llvmpipe the + // TextureRemintPullScenario's twin gives (ID-P9-11, DEBTS "to be attributed"): on llvmpipe the // kept-allocation case (GpuClearOverAnImmutableUploadSurvives - no re-mint to // serialize anything) read the pre-clear upload once on the push-monolith arm under // load, the same shape P9 measured 3/30 on the split arm. The cases ask what the @@ -502,7 +502,7 @@ void main() { o_color = texelFetch(u_tex, ivec2(gl_FragCoord.xy) % 4, 0); } ExpectImage(ImageCopy(t, 0, GL_RG8, "rg8"), kEdge, Solid(kEdge, 0x33, 0x99, 0, 255), 2); } - // Control: a signed-normalized level (not colour-renderable on every ES driver, so its + // Control: a signed-normalized level (not color-renderable on every ES driver, so its // readback may be refused and the shadow used instead), uploaded only. TEST_F(ImageBindableRemintScenario, SnormUploadSurvives) { if (!Ready()) return; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ImageLoadStoreSsoScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ImageLoadStoreSsoScenario.cpp index 7bf6ee2f..b7609c0d 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ImageLoadStoreSsoScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ImageLoadStoreSsoScenario.cpp @@ -277,7 +277,7 @@ void main() // the SPIR-V binding remap load-bearing. // // The remap (ProgramFactory::RemapDescriptorBindingsForVulkan) is what unifies bindings - // across stages and normalises every descriptor onto set 0; glslang hands it per-stage + // across stages and normalizes every descriptor onto set 0; glslang hands it per-stage // numbering that starts at 0 in EACH stage. It used to refuse any descriptor array that was // not a UBO, and its only complaint was an assert that compiles out above DEBUG - so a // release build carried on with the un-remapped numbering and a program holding an image @@ -288,7 +288,7 @@ void main() // to collide with and skipping the remap is indistinguishable from running it. Hence this // one - an image array AND a uniform block in the same fragment program, with the block // supplying the value that gets stored, so a mis-assigned binding shows up as the wrong - // colour rather than as nothing at all. + // color rather than as nothing at all. TEST_F(ImageLoadStoreSsoScenario, AnImageArrayAlongsideAnotherDescriptorKeepsBothBindings) { if (!Ready()) return; if (!ImagesAreUsable()) GTEST_SKIP() << "fewer than 8 image units"; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ImageSizeAfterRespecScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ImageSizeAfterRespecScenario.cpp index 038f9630..8b58b751 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ImageSizeAfterRespecScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ImageSizeAfterRespecScenario.cpp @@ -64,7 +64,7 @@ void main() )"; // Green when the image the unit currently holds has the size the application last gave - // it, red otherwise - the conformance case's own comparison, and its own colours. + // it, red otherwise - the conformance case's own comparison, and its own colors. constexpr const char* kFS = R"(#version 430 core layout(rgba8) readonly uniform image2D g_image; uniform ivec2 g_expected_size; @@ -151,7 +151,7 @@ void main() glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_color, 0); } - // Draw once with `expected` pushed to the shader and report the centre pixel. + // Draw once with `expected` pushed to the shader and report the center pixel. void DrawAndReadCentre(int expectedWidth, int expectedHeight, unsigned char (¢re)[4]) { const GLint location = glGetUniformLocation(m_program, "g_expected_size"); ASSERT_NE(location, -1) << "the program has no g_expected_size uniform"; @@ -222,7 +222,7 @@ void main() DrawAndReadCentre(16, 16, centre); EXPECT_EQ(static_cast(centre[0]), 0) - << "after the re-spec the draw still sees the OLD image size; centre pixel was (" + << "after the re-spec the draw still sees the OLD image size; center pixel was (" << static_cast(centre[0]) << ", " << static_cast(centre[1]) << ", " << static_cast(centre[2]) << ")"; EXPECT_EQ(static_cast(centre[1]), 255); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ImageTargetKindScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ImageTargetKindScenario.cpp index 50c71820..e8281ca9 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ImageTargetKindScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ImageTargetKindScenario.cpp @@ -32,7 +32,7 @@ // frontend could plausibly mishandle it. Mirroring it means a green scenario cannot be green // for a reason the conformance case excludes; // * glBindImageTexture with layered = GL_TRUE, which is what glBindImageTextures is specified -// to pass, and which is where a target kind whose layeredness a backend does not recognise +// to pass, and which is where a target kind whose layeredness a backend does not recognize // goes wrong. // // MULTISAMPLE is the one kind that is not merely an emulation problem, and the conformance case @@ -436,7 +436,7 @@ namespace MGITest { // clamped, and not an error - so every one of the four rows has to read the same texel // out of a target that has no layers, including the two rows that name layer 1 on a // texture whose only layer is 0. DirectGLES used to normalize `layered` and forward - // `layer` verbatim; Adreno honours the bogus layer by leaving the image unit reading + // `layer` verbatim; Adreno honors the bogus layer by leaving the image unit reading // zero, which is exactly the two rows KHR-GL42.bind_image_texture.single_layer failed. // // The bindings are checked back as well, because the fix depends on WHERE the @@ -596,7 +596,7 @@ namespace MGITest { // // KHR-GL42.bind_image_texture.single_layer's sweep, on the kinds whose backend target has // neither layers nor faces. Two of its four rows name layer 1 on a single-layer texture, - // which the spec says is to be ignored outright rather than honoured or rejected - and + // which the spec says is to be ignored outright rather than honored or rejected - and // which DirectGLES used to forward to the ES driver as written. #define MGL_DEFINE_LAYER_SWEEP_CASE(CaseName, Kind) \ diff --git a/MobileGL/MG_IntegrationTest/Scenarios/InPassClearScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/InPassClearScenario.cpp index 59372f72..6b8c0e51 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/InPassClearScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/InPassClearScenario.cpp @@ -15,7 +15,7 @@ // // * ORDER and SCISSOR: a draw, a scissored clear, a second draw - all in one pass. The clear // must land after the first draw and before the second, inside the scissor box only. -// * THE DRAW-BUFFER INDEX: VkClearAttachment::colorAttachment is the SUBPASS colour slot, which +// * THE DRAW-BUFFER INDEX: VkClearAttachment::colorAttachment is the SUBPASS color slot, which // the wire pass lays out by draw-buffer slot, not by framebuffer attachment point. With // glDrawBuffers({NONE, ATTACHMENT0}) a clear writes attachment 0 and leaves attachment 1 alone; // glClearBufferfv(GL_COLOR, 1, ...) is the same slot by number. @@ -326,7 +326,7 @@ void main() { o0 = texture(uPalette, vec2(0.5, 0.5)); } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // The palette changes every frame; this frame's colour is what the sprite must show. + // The palette changes every frame; this frame's color is what the sprite must show. const unsigned char texel[4] = {static_cast(frame == 2 ? 0 : 255), 255, 0, 255}; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, palette); @@ -336,7 +336,7 @@ void main() { o0 = texture(uPalette, vec2(0.5, 0.5)); } // Terrain: no depth test, red. glDisable(GL_DEPTH_TEST); Quad(1.0f, 0.0f, 0.0f, 1.0f, 0.5f); - // Sprites: depth-tested against the cleared depth, palette-coloured. + // Sprites: depth-tested against the cleared depth, palette-colored. glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glUseProgram(paletteProgram); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/IntegerBorderColorScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/IntegerBorderColorScenario.cpp index e2e44c18..52160942 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/IntegerBorderColorScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/IntegerBorderColorScenario.cpp @@ -9,17 +9,17 @@ // Scenario - AN INTEGER GL_TEXTURE_BORDER_COLOR REACHES AN isampler2D AS AN INTEGER. // // KHR-GL46.texture_border_clamp.Texture2D{R32I,R32UI} (and the 2DArray/3D siblings) set the border -// colour with glSamplerParameterIiv/Iuiv, sample outside the texture through an integer sampler and +// color with glSamplerParameterIiv/Iuiv, sample outside the texture through an integer sampler and // expect the value back. MobileGL returned 1132396544 on Espryt - which is 0x437F0000, the IEEE-754 -// bits of 255.0f, i.e. the float border-colour register read through an integer sampler - and 0 on +// bits of 255.0f, i.e. the float border-color register read through an integer sampler - and 0 on // Magma, where the border fell through to VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK. // // Two independent halves, and this scenario covers both because it goes through the frontend: // -// * the STATE had no record of which entry point wrote the border colour. All three +// * the STATE had no record of which entry point wrote the border color. All three // representations are kept numerically in step, so the value alone cannot say whether the // application called glTexParameterfv or glTexParameterIiv. -// * each backend then had exactly one border-colour call site: glTexParameterfv / +// * each backend then had exactly one border-color call site: glTexParameterfv / // glSamplerParameterfv on DirectGLES, and a snap-to-one-of-four-predefined-values on // DirectVulkan that never emitted the VK_BORDER_COLOR_INT_* family at all. // @@ -28,8 +28,8 @@ // nor opaque white, so on DirectVulkan it can only be delivered through VK_EXT_custom_border_color. // That makes the scenario a real test of the extension path on lavapipe rather than a palette hit. // -// Both an integer image view and an integer border colour are involved, which is the other half of -// the Vulkan rule: VK_BORDER_COLOR_FLOAT_* on an integer image view is undefined behaviour +// Both an integer image view and an integer border color are involved, which is the other half of +// the Vulkan rule: VK_BORDER_COLOR_FLOAT_* on an integer image view is undefined behavior // regardless of the value, so even a border of (0,0,0,1) has to resolve to INT_OPAQUE_BLACK. // InsideTexelsAreUnaffected is what keeps that from being asserted vacuously. @@ -190,7 +190,7 @@ void main() void ExpectBorderIsDelivered(const char* what) { for (int channel = 0; channel < 4; ++channel) { // (-0.5, -0.5) is a full texture width outside the image on both axes, so - // CLAMP_TO_BORDER can only answer with the border colour. + // CLAMP_TO_BORDER can only answer with the border color. const std::vector texels = RenderChannel(channel, -0.5f, -0.5f); EXPECT_EQ(FirstGLError(), 0u) << what << ": the border draw left a GL error behind"; ExpectAllTexels(what, channel, kBorderColor[channel], texels); @@ -266,7 +266,7 @@ void main() // The floor, and the control that keeps the two tests below from passing vacuously: an INSIDE // sample has to fetch the texture's own texel. If this fails the sampler, the shader or the - // integer readback is broken and nothing about the border colour has been measured. + // integer readback is broken and nothing about the border color has been measured. TEST_F(IntegerBorderColorScenario, InsideTexelsAreUnaffectedByTheBorderColour) { if (!Ready()) GTEST_SKIP(); @@ -297,7 +297,7 @@ void main() // The regression, sampler-object spelling - which is the one the conformance cases actually use, // and a separate code path in both backends (BackendSamplerObject::Sync on DirectGLES, and the - // sampler cache key on DirectVulkan, where a border colour that is not part of the key would + // sampler cache key on DirectVulkan, where a border color that is not part of the key would // alias two samplers that differ only in it). TEST_F(IntegerBorderColorScenario, SamplerParameterIivBorderColourSurvivesToAnIntegerSampler) { if (!Ready()) GTEST_SKIP(); @@ -311,7 +311,7 @@ void main() glSamplerParameterIiv(m_sampler, GL_TEXTURE_BORDER_COLOR, kBorderColor); ASSERT_EQ(FirstGLError(), 0u) << "sampler-object setup was rejected"; - // The texture object carries a DIFFERENT border colour, so a pass here cannot come from the + // The texture object carries a DIFFERENT border color, so a pass here cannot come from the // texture's own state leaking through: GL 4.6 core 8.10 says a bound sampler object's state // wins over the texture's for every sampling parameter. const std::int32_t decoyBorder[4] = {0, 0, 0, 0}; @@ -354,7 +354,7 @@ void main() // clamping to 0 is an equally defensible reading of the same paragraph, and DirectVulkan can be // made to produce either - but DirectGLES forwards the value to the ES driver verbatim and cannot // deviate, so choosing 0 would mean the same program sampling 0 on Magma and 255 on Espryt. The - // whole point of carrying the border colour's form is to stop that class of divergence, so the + // whole point of carrying the border color's form is to stop that class of divergence, so the // backends agree on the driver's answer. // // The clamp itself is still doing the work: without it the value reaches the driver as diff --git a/MobileGL/MG_IntegrationTest/Scenarios/InvalidImageUnitScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/InvalidImageUnitScenario.cpp index 23d9aa6d..4cfe958f 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/InvalidImageUnitScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/InvalidImageUnitScenario.cpp @@ -8,7 +8,7 @@ // // Scenario - AN IMAGE UNIT NAMES A TEXTURE, BUT NOT A TEXEL THE TEXTURE HAS. // -// UnboundImageDescriptorScenario's neighbour, one step further in: there the unit holds nothing, +// UnboundImageDescriptorScenario's neighbor, one step further in: there the unit holds nothing, // here it holds a real texture at a (level, layer) that texture does not have. GL 4.6 core 8.26 // makes every such access INVALID, and an invalid access is not an error at draw time: a load // returns zero in R, G and B, a store has no effect. It is the same observable an empty unit has. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/IoBlockNameCollisionScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/IoBlockNameCollisionScenario.cpp index 0d301d43..a857906f 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/IoBlockNameCollisionScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/IoBlockNameCollisionScenario.cpp @@ -29,9 +29,9 @@ // what says a red pixel in the colliding case is about the name and not about this machine's // tessellation, its geometry stage, or the block mechanism in general. // -// Colour code, so a failure names its own cause: +// Color code, so a failure names its own cause: // green - the payload crossed all four stage boundaries, which is the pass. -// blue - the clear colour: nothing was drawn at all (the program did not link, or the +// blue - the clear color: nothing was drawn at all (the program did not link, or the // backend program was rejected and every draw became a no-op). // red - the pipeline ran but the plain (non-block) varying did not arrive, i.e. the // failure is not about interface blocks. @@ -39,7 +39,7 @@ // zeroed or garbage. That is the defect this scenario exists for. // // llvmpipe and lavapipe run this faithfully but do NOT reproduce the original defect - the -// aliasing is a Mali ES compiler behaviour. Read a green run here as "the rename did not +// aliasing is a Mali ES compiler behavior. Read a green run here as "the rename did not // break the ordinary path"; the claim it pins on the device is the CTS group above. #include @@ -280,7 +280,7 @@ void main() return program; } - // Clears to BLUE, so "the draw painted nothing" is a colour of its own rather + // Clears to BLUE, so "the draw painted nothing" is a color of its own rather // than something that could be mistaken for a zeroed payload. Rgba8 DrawAndReadCentre(GLuint program) const { glViewport(0, 0, Gl().Width(), Gl().Height()); @@ -334,7 +334,7 @@ void main() // stages honestly, but nothing MobileGL reports answers for the geometry stage the // same way (GL_MAX_GEOMETRY_* are frontend constants and an ES driver may legitimately // report zero geometry storage blocks while having geometry shaders), so a stack that - // cannot build a five-stage program at all is recognised here, by trying. + // cannot build a five-stage program at all is recognized here, by trying. TEST_F(IoBlockNameCollisionScenario, DistinctlyNamedBlocksCarryThePayloadThroughFiveStages) { if (!Ready()) return; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/LargeArenaAdoptionScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/LargeArenaAdoptionScenario.cpp index 2f6e21eb..80ee680f 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/LargeArenaAdoptionScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/LargeArenaAdoptionScenario.cpp @@ -236,7 +236,7 @@ void main() { word = 0xC0FFEEu; } "MOBILEGL_PIPE_STATS=1, MOBILEGL_PIPE_STATS_PERIOD=1 and a private " "MOBILEGL_LOG_FILE_PATH. The ambient entries and the two subsystem " "arms configure none of that, and their log is shared - a read there " - "would race a neighbour's bring-up."; + "would race a neighbor's bring-up."; return; } if (!BuildMarkerIsSet("MGITEST_PIPE_PUSH_BUILD")) { diff --git a/MobileGL/MG_IntegrationTest/Scenarios/LayeredAttachmentBarrierScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/LayeredAttachmentBarrierScenario.cpp index 20dbca86..58fc4851 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/LayeredAttachmentBarrierScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/LayeredAttachmentBarrierScenario.cpp @@ -16,7 +16,7 @@ // and the copy read layer N. The layer the transfer touched was never transitioned: it sat in // COLOR_ATTACHMENT_OPTIMAL (or DEPTH_STENCIL_ATTACHMENT_OPTIMAL) while being read as TRANSFER_SRC. // -// That is undefined behaviour, not a guaranteed wrong pixel: a layout is a compression/tiling +// That is undefined behavior, not a guaranteed wrong pixel: a layout is a compression/tiling // promise, so a driver that stores both layouts identically returns the right bytes anyway. The // software lanes (lavapipe) are exactly such a driver, which is why this scenario is paired with a // validation-layer run - the layer names the mismatch outright @@ -26,8 +26,8 @@ // // The four cases below are the four transfer paths that take an attachment layer from GL: // -// glReadPixels (colour) -> VulkanRenderer::ReadPixels -// glBlitFramebuffer (colour) -> VulkanRenderer::BlitNamedFramebuffer +// glReadPixels (color) -> VulkanRenderer::ReadPixels +// glBlitFramebuffer (color) -> VulkanRenderer::BlitNamedFramebuffer // glReadPixels (GL_DEPTH_COMPONENT) -> VulkanRenderer::ReadDepthStencilImageToClient // glBlitFramebuffer (GL_DEPTH_BUFFER_BIT) -> VulkanRenderer::BlitNamedFramebuffer, depth leg // @@ -140,7 +140,7 @@ void main() { o_color = vec4(0.1, 0.2, 0.8, 1.0); } } } - // An RGBA8 2D array with a different uniform colour per layer. + // An RGBA8 2D array with a different uniform color per layer. GLuint MakeColorArray() { GLuint texture = 0; glGenTextures(1, &texture); @@ -172,7 +172,7 @@ void main() { o_color = vec4(0.1, 0.2, 0.8, 1.0); } return texture; } - // One FBO naming `layer` of the given arrays. Depth is optional (0 = colour only). + // One FBO naming `layer` of the given arrays. Depth is optional (0 = color only). GLuint MakeLayerFbo(GLuint colorArray, GLuint depthArray, int layer) { GLuint fbo = 0; glGenFramebuffers(1, &fbo); @@ -296,11 +296,11 @@ void main() { o_color = vec4(0.1, 0.2, 0.8, 1.0); } EXPECT_NEAR(blitted.g, kPaintedColor.g, 2); EXPECT_NEAR(blitted.b, kPaintedColor.b, 2); - ExpectOtherLayersUntouched(destinationArray, kDestinationLayer, "colour blit destination"); + ExpectOtherLayersUntouched(destinationArray, kDestinationLayer, "color blit destination"); // The source layer was rendered, not blitted into, so it is checked separately. const Rgba8 source = ReadLayer(sourceArray, kSourceLayer); EXPECT_NEAR(source.r, kPaintedColor.r, 2) << "blit source layer is " << Describe(source); - ExpectOtherLayersUntouched(sourceArray, kSourceLayer, "colour blit source"); + ExpectOtherLayersUntouched(sourceArray, kSourceLayer, "color blit source"); } // The depth aspect of the same readback path: the depth image sits in diff --git a/MobileGL/MG_IntegrationTest/Scenarios/LayeredAttachmentShapeScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/LayeredAttachmentShapeScenario.cpp index d5acddfc..93ccc320 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/LayeredAttachmentShapeScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/LayeredAttachmentShapeScenario.cpp @@ -48,7 +48,7 @@ // // One of them turned out not to be a DirectVulkan bug at all. glFramebufferTexture on // GL_DEPTH_STENCIL_ATTACHMENT is a shorthand the front end splits into a depth and a stencil -// attachment, and the split dropped the call's `layered` flag - so a layered colour attachment +// attachment, and the split dropped the call's `layered` flag - so a layered color attachment // sat beside a non-layered depth/stencil one and BOTH backends silently lost the draw. That is // the shape texture_cube_map_array.stencil_attachments_*_layered and // geometry_shader.layered_framebuffer.stencil_support are built on, and it is why they fail on @@ -93,11 +93,11 @@ namespace MGITest { // state-side HEIGHT, not in z, which is the whole reason it is here. constexpr int kOneDArrayLayers = 4; - // A colour no pass paints, uploaded before every draw. A layer that reads it back was + // A color no pass paints, uploaded before every draw. A layer that reads it back was // never rendered to. constexpr GLubyte kPoison = 0xAB; - // The glClear colour the two materialise cases use. Chosen as exact 8-bit values and fed + // The glClear color the two materialize cases use. Chosen as exact 8-bit values and fed // to glClearColor as n/255, so the round trip through a UNORM8 target is lossless and a // mismatch means a real miss rather than rounding. constexpr Rgba8 kClearColor{17, 68, 187, 255}; @@ -371,7 +371,7 @@ void main() return texture; } - // A cube map whose six faces are UPLOADED with their own colours - the same + // A cube map whose six faces are UPLOADED with their own colors - the same // ExpectedColor(face, 0) the painted cube of case (8) ends up holding, so both can be // checked with one expectation. Uploaded rather than rendered means the CPU shadow and // the image agree, which is the premise the BY-NAME readback needs; see case (8). @@ -407,7 +407,7 @@ void main() return texture; } - // A scratch 2D colour target for the sampling draw. It exists only so the draw has + // A scratch 2D color target for the sampling draw. It exists only so the draw has // somewhere to go that is NOT the layered attachment under test - a draw into that // would open a render pass and consume the pending clear through LOAD_OP_CLEAR, which // is the other consumer and the one that was already right. @@ -449,7 +449,7 @@ void main() glBindFramebuffer(GL_FRAMEBUFFER, 0); } - // Every texel of `texels` is the clear colour. +/-1 per channel, which no rounding can + // Every texel of `texels` is the clear color. +/-1 per channel, which no rounding can // exceed and which cannot be confused with the poison (0xAB) it replaced. void ExpectAllCleared(const std::vector& texels, int perTexelStride, const char* what) { for (std::size_t i = 0; i < texels.size(); ++i) { @@ -496,7 +496,7 @@ void main() return texels; } - // Every texel of every layer must be that layer's expected colour. Reported per layer + // Every texel of every layer must be that layer's expected color. Reported per layer // so a failure names which one, and the poison is called out by name. void ExpectEveryLayer(const std::vector& texels, int layers, int pass, const char* what) { for (int layer = 0; layer < layers; ++layer) { @@ -519,10 +519,10 @@ void main() } } - // Every texel of one cube FACE is that face's own colour. When it is not, the message - // says whose colour answered instead - which is the whole point here: a readback that + // Every texel of one cube FACE is that face's own color. When it is not, the message + // says whose color answered instead - which is the whole point here: a readback that // ignores the face token does not return garbage, it returns another face's perfectly - // plausible texels, and "+X's colour came back for -Y" is the sentence that names the + // plausible texels, and "+X's color came back for -Y" is the sentence that names the // defect. `what` is the spelling under test, since three of them read the same faces. void ExpectFaceColor(const std::vector& texels, int face, const char* what) { const Rgba8 expected = ExpectedColor(face, 0); @@ -535,7 +535,7 @@ void main() } else { for (int other = 0; other < 6; ++other) { if (other != face && actual == ExpectedColor(other, 0)) { - blame = std::string(" - which is face ") + kFaceNames[other] + "'s colour"; + blame = std::string(" - which is face ") + kFaceNames[other] + "'s color"; break; } } @@ -571,7 +571,7 @@ void main() std::vector m_programs; }; - // (1) A LAYERED GL_TEXTURE_3D colour attachment. Pre-fix this is the null VkImageView: + // (1) A LAYERED GL_TEXTURE_3D color attachment. Pre-fix this is the null VkImageView: // the attachment asked for a 3D view, whose [0, 4) layer span was measured against the // image's arrayLayers == 1 and refused, and VK_NULL_HANDLE went to vkCreateFramebuffer. TEST_F(LayeredAttachmentShapeScenario, LayeredThreeDColorAttachmentReachesEverySlice) { @@ -602,7 +602,7 @@ void main() glBindFramebuffer(GL_FRAMEBUFFER, 0); const std::vector texels = ReadLevel(GL_TEXTURE_3D, color, k3DSlices); EXPECT_EQ(FirstGLError(), 0u) << "reading the 3D level back errored"; - ExpectEveryLayer(texels, k3DSlices, /*pass=*/0, "layered GL_TEXTURE_3D colour attachment"); + ExpectEveryLayer(texels, k3DSlices, /*pass=*/0, "layered GL_TEXTURE_3D color attachment"); Gl().EndFrame(); } @@ -671,7 +671,7 @@ void main() Gl().EndFrame(); } - // (3) A LAYERED GL_TEXTURE_CUBE_MAP_ARRAY colour attachment. Pre-fix this is the other + // (3) A LAYERED GL_TEXTURE_CUBE_MAP_ARRAY color attachment. Pre-fix this is the other // exit: a valid CUBE_ARRAY view of a type no framebuffer may take, handed straight to // vkCreateFramebuffer. TEST_F(LayeredAttachmentShapeScenario, LayeredCubeMapArrayColorAttachmentReachesEveryLayerFace) { @@ -704,8 +704,7 @@ void main() glBindFramebuffer(GL_FRAMEBUFFER, 0); const std::vector texels = ReadLevel(GL_TEXTURE_CUBE_MAP_ARRAY, color, kCubeLayerFaces); EXPECT_EQ(FirstGLError(), 0u) << "reading the cube-map-array level back errored"; - ExpectEveryLayer(texels, kCubeLayerFaces, /*pass=*/0, - "layered GL_TEXTURE_CUBE_MAP_ARRAY colour attachment"); + ExpectEveryLayer(texels, kCubeLayerFaces, /*pass=*/0, "layered GL_TEXTURE_CUBE_MAP_ARRAY color attachment"); Gl().EndFrame(); } @@ -715,7 +714,7 @@ void main() // pass 0 paints at z = 0 against a depth buffer cleared to 1; // pass 1 paints at z = +0.5, which GL_LESS must reject. // - // A layer that reads back pass 1's colour is a layer the depth attachment never covered - + // A layer that reads back pass 1's color is a layer the depth attachment never covered - // which is exactly what attaching one layer-face of it, or none, looks like. Runs on both // backends: this is the cross-backend control for the packed case below. TEST_F(LayeredAttachmentShapeScenario, LayeredCubeMapArrayDepthAttachmentGatesEveryLayerFace) { @@ -741,7 +740,7 @@ void main() glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth, 0); glDrawBuffer(GL_COLOR_ATTACHMENT0); - ASSERT_EQ(FirstGLError(), 0u) << "attaching the layered colour + depth pair failed"; + ASSERT_EQ(FirstGLError(), 0u) << "attaching the layered color + depth pair failed"; ASSERT_TRUE(FramebufferIsComplete()); glViewport(0, 0, kExtent, kExtent); @@ -763,7 +762,7 @@ void main() const std::vector texels = ReadLevel(GL_TEXTURE_CUBE_MAP_ARRAY, color, kCubeLayerFaces); EXPECT_EQ(FirstGLError(), 0u) << "reading the cube-map-array level back errored"; ExpectEveryLayer(texels, kCubeLayerFaces, /*pass=*/0, - "layered cube-map-array depth attachment (pass 1's colour on a layer means the " + "layered cube-map-array depth attachment (pass 1's color on a layer means the " "depth test did not cover it)"); Gl().EndFrame(); @@ -783,12 +782,12 @@ void main() // point ITSELF was broken: glFramebufferTexture(GL_DEPTH_STENCIL_ATTACHMENT) is a // shorthand that the front end splits into a depth and a stencil attachment, and the split // dropped the call's `layered` flag (GL_Framebuffer.cpp, - // AttachFramebufferTextureWithUploadTarget). A layered colour attachment therefore sat + // AttachFramebufferTextureWithUploadTarget). A layered color attachment therefore sat // beside a NON-layered depth/stencil one, and both backends lost the draw entirely - with // no GL error and glCheckFramebufferStatus answering COMPLETE. DirectVulkan built the // depth/stencil view with layerCount 1 under a framebuffer declaring 12 layers // (VUID-VkFramebufferCreateInfo-flags-04535, which the validation layers report on this - // exact case); DirectGLES attached one layer of it beside a layered colour target, which + // exact case); DirectGLES attached one layer of it beside a layered color target, which // the driver answers with GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS. Case (4) above is what // isolates it to the attachment point: the same cube-map array on GL_DEPTH_ATTACHMENT // rendered and gated correctly throughout. @@ -816,7 +815,7 @@ void main() glViewport(0, 0, kExtent, kExtent); glDisable(GL_SCISSOR_TEST); - // The probe: its own colour attachment (so the subject texture keeps its poison), the + // The probe: its own color attachment (so the subject texture keeps its poison), the // same depth-stencil attachment, and both tests off - so every layer-face must come // back painted, whatever the gating below then decides. { @@ -826,7 +825,7 @@ void main() glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, probeColor, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencil, 0); glDrawBuffer(GL_COLOR_ATTACHMENT0); - ASSERT_EQ(FirstGLError(), 0u) << "attaching the layered colour + depth-stencil pair failed"; + ASSERT_EQ(FirstGLError(), 0u) << "attaching the layered color + depth-stencil pair failed"; ASSERT_TRUE(FramebufferIsComplete()); glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); @@ -836,10 +835,10 @@ void main() ReadLevel(GL_TEXTURE_CUBE_MAP_ARRAY, probeColor, kCubeLayerFaces); EXPECT_EQ(FirstGLError(), 0u) << "the probe draw or readback errored"; ExpectEveryLayer(probeTexels, kCubeLayerFaces, /*pass=*/3, - "a layered draw with the depth and stencil tests DISABLED, into a colour + " + "a layered draw with the depth and stencil tests DISABLED, into a color + " "GL_DEPTH_STENCIL_ATTACHMENT cube-map-array pair (all poison means the " "attachment pair lost the draw outright, which is what a non-layered " - "depth/stencil attachment beside a layered colour one looks like)"); + "depth/stencil attachment beside a layered color one looks like)"); // The gating assertions below can only add noise once the shape itself is broken. if (::testing::Test::HasNonfatalFailure()) return; } @@ -849,7 +848,7 @@ void main() glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencil, 0); glDrawBuffer(GL_COLOR_ATTACHMENT0); - ASSERT_EQ(FirstGLError(), 0u) << "attaching the layered colour + depth-stencil pair failed"; + ASSERT_EQ(FirstGLError(), 0u) << "attaching the layered color + depth-stencil pair failed"; ASSERT_TRUE(FramebufferIsComplete()); glDepthMask(GL_TRUE); @@ -883,7 +882,7 @@ void main() const std::vector texels = ReadLevel(GL_TEXTURE_CUBE_MAP_ARRAY, color, kCubeLayerFaces); EXPECT_EQ(FirstGLError(), 0u) << "reading the cube-map-array level back errored"; ExpectEveryLayer(texels, kCubeLayerFaces, /*pass=*/0, - "layered cube-map-array depth-stencil attachment (a later pass's colour means " + "layered cube-map-array depth-stencil attachment (a later pass's color means " "the depth or stencil test did not cover that layer)"); Gl().EndFrame(); @@ -909,7 +908,7 @@ void main() // earlier cases use both carry their count in z, so they agree either way and cannot see it. // // The draw goes into a scratch 2D target, never into the layered attachment, so the - // materialise path is the only consumer that can fire. + // materialize path is the only consumer that can fire. TEST_F(LayeredAttachmentShapeScenario, LayeredCubeMapClearMaterialisedBySamplingReachesEveryFace) { if (!Ready()) return; @@ -943,13 +942,13 @@ void main() // // Not glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face): when this case was written // that spelling could not see per-face state on DirectVulkan at all - measured against - // a tree where only +X had been cleared it returned the cleared colour for all six + // a tree where only +X had been cleared it returned the cleared color for all six // faces - so a case built on it would have been unfalsifiable. That is a readback // defect rather than an attachment one, and case (8) below is where it is pinned and // fixed; this case keeps the independent spelling deliberately, because it must go on // measuring the CLEAR whatever the readback does. glFramebufferTexture2D + // glReadPixels names one face and nothing else, and the pending clear is long gone by - // now (materialised and popped above), so this readback cannot alter what it is + // now (materialized and popped above), so this readback cannot alter what it is // measuring. for (int face = 0; face < 6; ++face) { const GLuint faceFbo = TrackFramebuffer(); @@ -964,7 +963,7 @@ void main() glBindFramebuffer(GL_FRAMEBUFFER, 0); EXPECT_EQ(FirstGLError(), 0u) << "reading cube face " << kFaceNames[face] << " back errored"; ExpectAllCleared(texels, kExtent * kExtent, - (std::string("layered GL_TEXTURE_CUBE_MAP glClear materialised by sampling, " + (std::string("layered GL_TEXTURE_CUBE_MAP glClear materialized by sampling, " "face ") + kFaceNames[face]) .c_str()); @@ -1014,16 +1013,16 @@ void main() glBindTexture(GL_TEXTURE_1D_ARRAY, 0); EXPECT_EQ(FirstGLError(), 0u) << "reading the 1D-array level back errored"; ExpectAllCleared(texels, kExtent, - "layered GL_TEXTURE_1D_ARRAY glClear materialised by sampling (unit = layer)"); + "layered GL_TEXTURE_1D_ARRAY glClear materialized by sampling (unit = layer)"); Gl().EndFrame(); } - // (8) THE CUBE FACE TOKEN A READBACK IS GIVEN, AND WHETHER IT HONOURS IT. + // (8) THE CUBE FACE TOKEN A READBACK IS GIVEN, AND WHETHER IT HONORS IT. // // Case (6) above had to route around glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face) // entirely: measured against a tree where only the +X face had been cleared, that spelling - // returned +X's colour for all six face tokens. This case is that observation turned into + // returned +X's color for all six face tokens. This case is that observation turned into // an assertion, and it is about the READBACK, not the attachment. // // THE DEFECT. DirectVulkan's GetTextureImage derived its copy geometry from the IMAGE's @@ -1045,7 +1044,7 @@ void main() // the one face's worth of buffer a single-face read has any reason to pass was rejected as // too small. // - // Each face is painted its OWN colour, so a collapse onto layer 0 does not merely read + // Each face is painted its OWN color, so a collapse onto layer 0 does not merely read // "wrong": the failure names the face that answered. The cube is poisoned first and then // painted through the GPU, so an answer served from the stale CPU shadow is also called out // by name rather than passing. And the per-face FBO + glReadPixels read is the control: it @@ -1061,7 +1060,7 @@ void main() const GLuint cube = MakePoisonedCubeMap(); ASSERT_EQ(FirstGLError(), 0u) << "creating the RGBA8 cube map failed"; - // Paint every face its own colour through an FBO that names that one face. A clear + // Paint every face its own color through an FBO that names that one face. A clear // rather than a draw, so nothing here depends on a shader stage being present. glDisable(GL_SCISSOR_TEST); glDisable(GL_DEPTH_TEST); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/MagmaRunAheadScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/MagmaRunAheadScenario.cpp index 045c9100..02d638b2 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/MagmaRunAheadScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/MagmaRunAheadScenario.cpp @@ -188,7 +188,7 @@ void main(){vec2 p[3]=vec2[3](vec2(-1,-1),vec2(3,-1),vec2(-1,3));gl_Position=vec ExpectQueued(2); hold.Release(); // Resource creation requires a reply, and storage definitions may require an - // allocation acknowledgement. Do not hold the apply owner across those legal + // allocation acknowledgment. Do not hold the apply owner across those legal // waits. There is still no GPU readback/Finish before all four draws, so the // old GPU store must survive respecify and deletion until its draws complete. glBufferData(GL_ARRAY_BUFFER, sizeof(b), b.data(), GL_STREAM_DRAW); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/MagmaVertexLayoutScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/MagmaVertexLayoutScenario.cpp index ea1082c4..6b523596 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/MagmaVertexLayoutScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/MagmaVertexLayoutScenario.cpp @@ -152,7 +152,7 @@ void main() { color = vec4(vTint, 1.0); })"; } std::array ClearDrawRead(GLuint program) { - glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // blue: the "the draw did not land" colour + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // blue: the "the draw did not land" color glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); glBindVertexArray(m_vao); @@ -173,7 +173,7 @@ void main() { color = vec4(vTint, 1.0); })"; // THE ASSERTION IS THAT THE PROCESS IS STILL HERE and that the framebuffer still holds the // clear, which together say "declined" rather than "rendered wrong pixels". A gtest case // cannot assert the absence of an abort any more directly than by reaching its next - // statement: the old behaviour took the whole binary down, so every case after this one in + // statement: the old behavior took the whole binary down, so every case after this one in // the lane was equally the control. TEST_F(MagmaVertexLayoutScenario, AnUnmappableVertexFormatDeclinesTheDrawInsteadOfEndingTheSession) { if (!Ready() || IsSkipped()) return; @@ -189,7 +189,7 @@ void main() { color = vec4(vTint, 1.0); })"; EXPECT_NEAR(pixel[i], blue[i], 1) << "component " << i << ": the draw was expected to DECLINE (leaving the clear " - "colour) because location 1 is an enabled GL_FIXED array the program reads " + "color) because location 1 is an enabled GL_FIXED array the program reads " "and Vulkan has no format for it. A non-clear pixel means the attribute was " "silently replaced by the current vertex attribute value, which is the exact " "wrong-pixels outcome the monolith arm's pre-flight refuses."; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/MagmaWireReclaimScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/MagmaWireReclaimScenario.cpp index 5f131415..5fd8e4cc 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/MagmaWireReclaimScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/MagmaWireReclaimScenario.cpp @@ -138,7 +138,7 @@ void main() { fragColor = color[0]; })"; out[i] = quad[i]; } - // A colour per strip that no neighbour shares and the clear (all zero) is not. + // A color per strip that no neighbor shares and the clear (all zero) is not. Rgba8 StripColor(int strip) { Rgba8 c; c.r = static_cast(40 + (strip * 37) % 200); @@ -298,7 +298,7 @@ void main() { fragColor = color[0]; })"; // Every orphan is named by recorded, unsubmitted work; only the watermark's forced sync // point can retire it before the frame ends. Before M2: 48 MiB parked against the lane's // 8 MiB budget. The strips are the soundness half: a store destroyed while its draw was - // still pending does not leave its own colour behind. + // still pending does not leave its own color behind. TEST_F(MagmaWireReclaimScenario, RespecifyAndDrawEachStoreInOneFrameStaysWithinTheDeferredBudget) { if (!Ready() || IsSkipped()) return; const PipeStatsWindow::LogMark mark = SetupFrame(); @@ -412,7 +412,7 @@ void main() { fragColor = color[0]; })"; // Fatal. The fix folds VkBufferManager's wire-store destroy epoch into both memos. // // THE SHAPE, all in one frame, every step deterministic (no sleep, no fence poll race): - // 1. D1 draws with UBO store S1 (256 B, colour A): the memo now maps S1's handle to + // 1. D1 draws with UBO store S1 (256 B, color A): the memo now maps S1's handle to // D1's descriptor set. // 2. glBufferData(U, 0) orphans S1 - parked, tagged for the batch D1 is recorded in - // and mints nothing in its place, so the handle value stays free once S1 dies. @@ -426,7 +426,7 @@ void main() { fragColor = color[0]; })"; // 6. glBufferData(V, 0) parks the vertex store, and THAT park's sweep finds S1's // batch complete and destroys S1: its handle value is free, its memory a 256-byte // hole bounded by the pin store minted right after it. - // 7. glBufferData(U, 64 KiB, colour B) mints through the freed handle value; 64 KiB + // 7. glBufferData(U, 64 KiB, color B) mints through the freed handle value; 64 KiB // cannot land in the hole, so the dead store's bytes stay where D1's set points. // 8. D2 draws with U: it resolves (S1's handle value, 16 bytes) - a memo hit before // the fix, and D1's set reads A off the dead store. @@ -446,7 +446,7 @@ void main() { fragColor = color[0]; })"; const Rgba8 colourA{200, 60, 30, 255}; const Rgba8 colourB{60, 200, 90, 255}; const auto blockBytes = [](std::size_t size, const Rgba8& c) { - // The block's vec4 at offset 0; every other slot holds a colour no step draws, so a + // The block's vec4 at offset 0; every other slot holds a color no step draws, so a // read off any other offset is as visible as a read off the dead store. std::vector bytes(size, 0); float* f = reinterpret_cast(bytes.data()); @@ -510,7 +510,7 @@ void main() { fragColor = color[0]; })"; const Rgba8 got = image.At(kWidth / 2, kHeight / 2); EXPECT_TRUE(Near(got, colourB)) << "read " << got << ", wanted " << colourB << " (the live store's bytes). " << colourA - << " is the DEAD store's colour: the draw through the re-minted VkBuffer handle reused a " + << " is the DEAD store's color: the draw through the re-minted VkBuffer handle reused a " "descriptor set memoized under the first store's handle and read its freed memory " "(ID-P7-43); anything else is that memory already reused"; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/MultiDrawScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/MultiDrawScenario.cpp index fc6d313d..17f5e97c 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/MultiDrawScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/MultiDrawScenario.cpp @@ -84,7 +84,7 @@ void main() { float r, g, b; }; - // Four column quads spanning the viewport left to right, in four colours, + // Four column quads spanning the viewport left to right, in four colors, // so a sub-draw that lands in the wrong place, draws the wrong vertices or // does not draw at all changes the picture rather than hiding inside it. constexpr int kColumns = 4; @@ -452,7 +452,7 @@ void main() { } // Same, with GL_UNSIGNED_SHORT: the sentinel a rewritten stream has to - // recognise is the index TYPE's all-ones value, not the rewritten stream's. + // recognize is the index TYPE's all-ones value, not the rewritten stream's. TEST_F(MultiDrawScenario, PrimitiveRestartUnsignedShortBatchMatchesUnrolledDraws) { if (!Ready()) return; constexpr int kPad = 5; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ObjectSubsystemControlScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ObjectSubsystemControlScenario.cpp index e726d9bb..32e36709 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ObjectSubsystemControlScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ObjectSubsystemControlScenario.cpp @@ -43,7 +43,7 @@ // D-K2's dependency refusal. Every MGPBoundView::Texture and MGPImageView::Res names a // Texture handle and only bit 10 populates the texture slot table, so a sampler subsystem // without it would miss every lookup and walk on without unbinding. The bring-up logs ONE -// error naming BOTH bits, refuses bit 11 and runs the legacy sampler arm - modelled on the +// error naming BOTH bits, refuses bit 11 and runs the legacy sampler arm - modeled on the // bit-8-requires-bit-7 refusal of ResolveVertexInputSubsystemArm (since removed). The assertion is // that the refusal is NAMED and that the run then produces the same pixels as any other // lane: a refusal that half-ran, or that aborted, would both be failures here. @@ -63,8 +63,8 @@ // stated reason is worse than no assertion (review F-M6). // // every lane -// THE PIXELS MUST NOT MOVE. The workload draws one solid-colour quad through a texture, an -// explicit sampler object and a user framebuffer, and every lane must read back that colour. +// THE PIXELS MUST NOT MOVE. The workload draws one solid-color quad through a texture, an +// explicit sampler object and a user framebuffer, and every lane must read back that color. // "The counters moved and the picture did not" is the whole claim - a switch that changed // what is drawn would not be an A/B, it would be a bug. // @@ -541,7 +541,7 @@ void main() { oColor = texture(uTex, vUv); } } else { FAIL() << "unknown " << kLaneMarker << " value '" << m_lane << "': the arms are on / off / refused / refused-texture / consumer / " - "no-consumer. Reading an unrecognised name as any of them would make " + "no-consumer. Reading an unrecognized name as any of them would make " "this lane assert another arm's expectation while claiming to test " "this one."; } @@ -587,11 +587,11 @@ void main() { oColor = texture(uTex, vUv); } // The refusal is decided from the bitmask, but it is a BACKEND's decision: D-K2 puts it // in ResolveSamplersSubsystemArm(), beside the bit-8-requires-bit-7 refusal that // already ships, and that function is package D's (Managers.cpp). A backend that does - // not yet honour P4a's mask at all cannot refuse a dependency inside it, so on such a + // not yet honor P4a's mask at all cannot refuse a dependency inside it, so on such a // tree there is nothing here to find and this case SKIPS rather than reporting the // absence of an unimplemented subsystem as a failure. The marker is the same one // HandleRecycle's P4a cases read - "does any source under this backend name one of the - // four P4a subsystem constants" - because naming the constant is exactly what honouring + // four P4a subsystem constants" - because naming the constant is exactly what honoring // the mask means. { const std::string& backend = Gl().BackendName(); @@ -603,7 +603,7 @@ void main() { oColor = texture(uTex, vUv); } "MobileGL/MG_Backend/" << backend << " names any of kMGPipeSubsystem{Framebuffer, TextureResources, " - "Samplers, Programs}, so this backend does not honour P4a's mask " + "Samplers, Programs}, so this backend does not honor P4a's mask " "and cannot refuse a dependency inside it. D-K2's refusal lives " "in ResolveSamplersSubsystemArm() beside the bit-8-requires-bit-7 " "one ResolveVertexInputSubsystemArm made (since removed), in " @@ -638,7 +638,7 @@ void main() { oColor = texture(uTex, vUv); } "resource subsystem (bit 10) it depends on, and no single ERROR line of the " "library's log both says it REFUSED and names the two bits. D-K2 requires ONE " "MGLOG_E naming both and a fall back to the legacy sampler arm; a mask that is " - "silently half-honoured is the failure this case exists to catch, and it is " + "silently half-honored is the failure this case exists to catch, and it is " "invisible in the pixels by construction. The set bit may be spelled by the " "constant's name, '(bit 11)' or '0x800', before ' is set but '; the needed bit " "must be the helper's 'missing 0x400)' field after it. The log was " @@ -677,11 +677,11 @@ void main() { oColor = texture(uTex, vUv); } // texture family's Resolve*SubsystemArm - package D's Managers.cpp - and this case is the // pin that says it is there. // - // ON A TREE WHOSE BACKEND DOES NOT HONOUR P4a's MASK THIS SKIPS, NAMED, exactly as the + // ON A TREE WHOSE BACKEND DOES NOT HONOR P4a's MASK THIS SKIPS, NAMED, exactly as the // 0x9ff case does and for the same reason: a backend that never reads the four constants // cannot refuse a dependency between two of them, and reporting the absence of an // unimplemented subsystem as a failure is what ID-2 forbids. Once the backend DOES name - // them the case is a hard pin, which is the point - if D's texture-family resolver honours + // them the case is a hard pin, which is the point - if D's texture-family resolver honors // the mask and does not carry this row, this entry is where that shows. // // WHAT THIS ARM DOES ON THE INTEGRATED TREE, corrected (review F-v2-m2). An earlier @@ -692,7 +692,7 @@ void main() { oColor = texture(uTex, vUv); } // case matches - so the arm ARMS AND PASSES. A red here is therefore a real finding about // that resolver (it stopped refusing, refused for the wrong reason, or printed the mirror // sentence, which the direction check above is what catches) and must not be waved - // through as a sequencing artefact. + // through as a sequencing artifact. // ------------------------------------------------------------------------------------ TEST_F(ObjectSubsystemControlScenario, ATextureBitWithoutTheSamplerBitIsRefusedAndNamed) { if (!Ready()) return; @@ -717,7 +717,7 @@ void main() { oColor = texture(uTex, vUv); } "MobileGL/MG_Backend/" << backend << " names any of kMGPipeSubsystem{Framebuffer, TextureResources, " - "Samplers, Programs}, so this backend does not honour P4a's mask " + "Samplers, Programs}, so this backend does not honor P4a's mask " "and cannot refuse a dependency inside it. D-K2's fourth row " "(bit 10 requires bit 11, ID-15) lives in the texture family's " "Resolve*SubsystemArm beside the bit-11-requires-bit-10 and " diff --git a/MobileGL/MG_IntegrationTest/Scenarios/OrientationScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/OrientationScenario.cpp index f90a8b1f..17262c90 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/OrientationScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/OrientationScenario.cpp @@ -18,17 +18,17 @@ // unflipped flags and the whole frame rendered upside down (retrace SSIM 0.052, // deterministic; flickering clouds on device). // -// What pins it: a pattern asymmetric in BOTH axes - four quadrants, coloured +// What pins it: a pattern asymmetric in BOTH axes - four quadrants, colored // // top-left RED | WHITE top-right // bottom-left BLUE | GREEN bottom-right // // - drawn to a target, read back with glReadPixels, and reduced to the four -// quadrant-centre colours in the fixed order bottom-left, bottom-right, +// quadrant-center colors in the fixed order bottom-left, bottom-right, // top-left, top-right. // // Four quadrants rather than the three horizontal stripes this scenario used to -// draw, because stripes only pin ONE axis. Stripes read down the centre line +// draw, because stripes only pin ONE axis. Stripes read down the center line // are unchanged by an X flip, by a transpose, and by a 180 rotation composed // with a Y flip: all three of those bugs would have rendered a green stripe // between a blue one and a red one and passed. Every one of the eight @@ -45,7 +45,7 @@ // // The assertions then go further than the signature: every quadrant is checked // pixel by pixel over its whole area (RegionIsMostly), so a partial or torn -// draw cannot pass by having the four sampled centres come out right. +// draw cannot pass by having the four sampled centers come out right. // // Both orderings are covered, because the memo is poisoned by whichever pass // runs first and these tests share one process: @@ -102,7 +102,7 @@ void main() { // "every single pixel" an achievable (and therefore useful) demand. constexpr int kQuadrantInset = 2; - // A deliberately asymmetric sub-rect of the 128x96 surface: neither centred nor + // A deliberately asymmetric sub-rect of the 128x96 surface: neither centered nor // full-extent in either axis, mirroring the conformance suite's randomised // sub-viewport geometry (glcShaderRenderCase.cpp:735-741). Asymmetry is the whole // point - y == H - y - h is exactly the case an unconverted Y origin gets right by @@ -223,7 +223,7 @@ void main() { } // The signature says WHICH transform went wrong; this says the whole - // image is right, not merely its four sampled centres. + // image is right, not merely its four sampled centers. void ExpectUprightQuadrants(const Image& image, const std::string& when) { const int w = image.Width(); const int h = image.Height(); @@ -333,8 +333,8 @@ void main() { const int w = upright.Width(); const int h = upright.Height(); - // Transposes are expressed on the largest centred square the readback - // contains, which is enough for the four quadrant centres to move. + // Transposes are expressed on the largest centered square the readback + // contains, which is enough for the four quadrant centers to move. const int side = std::min(w, h); const int ox = (w - side) / 2; const int oy = (h - side) / 2; @@ -373,7 +373,7 @@ void main() { } // The four symmetries that move the axes into each other. They only - // make sense on a square, so they run on the largest centred one. + // make sense on a square, so they run on the largest centered one. struct SquareSymmetry { const char* name; const char* expected; @@ -430,7 +430,7 @@ void main() { // shape where the two cancel. // Placement: a sub-viewport draw must land in GL rows [y0, y0+h), not mirrored about the - // surface centre. Read back full-extent, which is the path that already worked, so a + // surface center. Read back full-extent, which is the path that already worked, so a // failure here can only be the viewport's Y origin. TEST_F(OrientationScenario, SubViewportDrawLandsWhereGLPutsIt) { BindDefaultFramebuffer(); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/OversizedRecordingSplitScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/OversizedRecordingSplitScenario.cpp index 7b37be01..ffaa2b53 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/OversizedRecordingSplitScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/OversizedRecordingSplitScenario.cpp @@ -85,7 +85,7 @@ void main() { )"; // The state cases: the unit-square vertices (or a triangle of them) stretched over an - // NDC rectangle at a given depth, in a uniform colour. A zero rectangle makes a + // NDC rectangle at a given depth, in a uniform color. A zero rectangle makes a // zero-area primitive - a draw that reaches the renderer and rasterizes nothing. constexpr const char* kRectVS = R"(#version 330 core in vec2 aPos; @@ -174,9 +174,9 @@ void main() { o_color = vec4(1.0); } return ::testing::AssertionSuccess(); } return ::testing::AssertionFailure() - << wrong << " of " << kDraws << " pixels do not hold their own draw's colour. First: (" << firstX + << wrong << " of " << kDraws << " pixels do not hold their own draw's color. First: (" << firstX << ", " << firstY << ") = " << firstSeen << ", drawn by draw " << (firstY * kSide + firstX) - << " (a pixel no draw reached still holds the clear colour 0,0,0,0)"; + << " (a pixel no draw reached still holds the clear color 0,0,0,0)"; } // Every pixel of columns [x0, x1] (all rows) is `expected`, each channel within `tolerance`. @@ -353,7 +353,7 @@ void main() { o_color = vec4(1.0); } } // namespace // kDraws single-pixel quads into a fresh target, one uniform value per draw, with no - // readback, flush or rebind in between. Every pixel must hold its own draw's colour. + // readback, flush or rebind in between. Every pixel must hold its own draw's color. TEST_F(OversizedRecordingSplitScenario, EveryDrawOfTheFrameLandsAcrossCommandBufferSplits) { if (!Ready()) return; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/P4aFinalFixScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/P4aFinalFixScenario.cpp index 3066fea3..910e8396 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/P4aFinalFixScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/P4aFinalFixScenario.cpp @@ -154,7 +154,7 @@ void main() { oColor = texture(uTex, vUv); } return texels; } - // A 4x4 level 0 of one colour, NEAREST_MIPMAP_NEAREST with the level range clamped + // A 4x4 level 0 of one color, NEAREST_MIPMAP_NEAREST with the level range clamped // to `maxLevel`, so a single-level texture is complete and a chain is complete once // its levels exist. static GLuint MakeLevel0(std::uint8_t r, std::uint8_t g, std::uint8_t b, int maxLevel, int size = 4) { @@ -209,7 +209,7 @@ void main() { oColor = texture(uTex, vUv); } const int cx = image.Width() / 2; const int cy = image.Height() / 2; std::cout << "[ P4aFinalFix ] case=" << caseName << " backend=" << Gl().BackendName() - << " MOBILEGL_PIPE_PUSH=" << (mask ? mask : "(unset)") << " centre=" << image.At(cx, cy) + << " MOBILEGL_PIPE_PUSH=" << (mask ? mask : "(unset)") << " center=" << image.At(cx, cy) << " (" << image.ColorName(cx, cy) << ")" << std::endl; } @@ -446,7 +446,7 @@ void main() { oColor = texture(uTex, vUv); } // A sampler object bound to the unit the draw samples through, deleted while bound: GL // unbinds it from every unit at glDeleteSamplers, and the texture's own parameters apply - // again. Both draws must be the texture's colour. + // again. Both draws must be the texture's color. TEST_F(P4aFinalFixScenario, ASamplerObjectDeletedWhileBoundLeavesTheNextDrawIntact) { if (!Ready()) return; const GLuint texture = MakeLevel0(255, 0, 0, /*maxLevel=*/0); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/P4aSeamAuditScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/P4aSeamAuditScenario.cpp index 0b423ad2..57870080 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/P4aSeamAuditScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/P4aSeamAuditScenario.cpp @@ -95,7 +95,7 @@ void main() { oColor = uColor; } )"; // texelFetch, so WHICH image the unit holds is the whole answer and no filter, wrap or - // completeness rule can explain a colour away. + // completeness rule can explain a color away. constexpr const char* kFetchFS = R"(#version 330 core uniform sampler2D uTex; out vec4 oColor; @@ -104,7 +104,7 @@ void main() { oColor = texelFetch(uTex, ivec2(0, 0), 0); } // texture() at (1.5, 1.5): outside the image on both axes, so the WRAP mode of whichever // sampler applies - the unit's sampler object or the texture's built-in one - decides - // whether the texel or the border colour comes back. + // whether the texel or the border color comes back. constexpr const char* kOutsideSampleFS = R"(#version 330 core uniform sampler2D uTex; out vec4 oColor; @@ -191,7 +191,7 @@ void main() { imageStore(i1, 0, imageLoad(i0, 0) + uvec4(2u, 0u, 0u, 0u)); } return false; } - // A 2x2 RGBA8 texture filled with one colour, NEAREST, single level - complete under + // A 2x2 RGBA8 texture filled with one color, NEAREST, single level - complete under // every rule, so nothing about completeness can enter the F-1 and F-4 sequences. static GLuint MakeSolidTexture2D(std::uint8_t r, std::uint8_t g, std::uint8_t b) { std::uint8_t texels[2 * 2 * 4]; @@ -311,7 +311,7 @@ void main() { imageStore(i1, 0, imageLoad(i0, 0) + uvec4(2u, 0u, 0u, 0u)); } glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); ASSERT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), static_cast(GL_FRAMEBUFFER_COMPLETE)) - << "an SRGB8 colour attachment must be complete (natively or through the widening)"; + << "an SRGB8 color attachment must be complete (natively or through the widening)"; glViewport(0, 0, kSize, kSize); glUseProgram(program); glUniform4f(colorLocation, 0.0f, 1.0f, 0.0f, 0.25f); @@ -497,7 +497,7 @@ void main() { imageStore(i1, 0, imageLoad(i0, 0) + uvec4(2u, 0u, 0u, 0u)); } glUniform4f(colorLocation, 0.0f, 1.0f, 0.0f, 0.25f); DrawQuad(); // dst = stored alpha; src factor GL_DST_ALPHA, dst factor GL_ZERO, source white => - // the colour becomes (storedAlpha, storedAlpha, storedAlpha) - ThreeChannelAttachment's + // the color becomes (storedAlpha, storedAlpha, storedAlpha) - ThreeChannelAttachment's // own probe, which nothing on the readback path can doctor. glEnable(GL_BLEND); glBlendFunc(GL_DST_ALPHA, GL_ZERO); @@ -737,7 +737,7 @@ void main() { imageStore(i1, 0, imageLoad(i0, 0) + uvec4(2u, 0u, 0u, 0u)); } // The texture's built-in sampler REPEATS, so (1.5, 1.5) reads the red texel through it; // the sampler object CLAMPS TO A WHITE BORDER, so the same coordinate reads white - // through it. White is a Vulkan palette border colour, so Magma needs no extension. + // through it. White is a Vulkan palette border color, so Magma needs no extension. const GLuint red = MakeSolidTexture2D(255, 0, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PackedWordReadbackScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PackedWordReadbackScenario.cpp index e1da335c..ef9370a8 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PackedWordReadbackScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PackedWordReadbackScenario.cpp @@ -10,7 +10,7 @@ // words the image HOLDS, and KHR-GL43.copy_image compares exactly those words. Two routes used to // answer, and both are wrong for a level glCopyImageSubData wrote: // -// * the colour-attachment route reads GL_RGBA/GL_FLOAT and re-encodes, which canonicalizes an +// * the color-attachment route reads GL_RGBA/GL_FLOAT and re-encodes, which canonicalizes an // RGB9_E5 shared exponent and collapses an R11F_G11F_B10F NaN payload to 1; // * the CPU shadow only holds what was UPLOADED, and the mirror that replays a copy into it // declines - silently - for a renderbuffer source, which has no shadow to mirror from. @@ -141,7 +141,7 @@ namespace MGITest { }; // The control that has to hold before either regression means anything: a packed word - // uploaded and read straight back must be the SAME word, not merely the same colour. + // uploaded and read straight back must be the SAME word, not merely the same color. TEST_F(PackedWordReadbackScenario, AnUploadedPackedWordReadsBackVerbatim) { if (!Ready()) GTEST_SKIP(); @@ -160,7 +160,7 @@ namespace MGITest { // physically holds the source's word - but the readback decoded it to float and re-encoded, // and the destination's blue field is a NaN whose payload float32 does not carry. Every // texel came back 0xf87c0000 (payload 1) instead of 0xf8fc0000 (payload 3): the same - // "colour", two bits apart. + // "color", two bits apart. TEST_F(PackedWordReadbackScenario, ACopiedRgb9E5WordSurvivesInAnR11fG11fB10fDestination) { if (!Ready()) GTEST_SKIP(); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PartialUploadOverGpuContentScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PartialUploadOverGpuContentScenario.cpp index ec5ed806..4b9c446b 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PartialUploadOverGpuContentScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PartialUploadOverGpuContentScenario.cpp @@ -682,7 +682,7 @@ void main() { } // A hundred 2x2 boxes two texels apart: more than the 96 rects the storage keeps, so its - // list folds neighbours together, gaps and all. + // list folds neighbors together, gaps and all. TEST_F(PartialUploadOverGpuContentScenario, AHundredSubImagesKeepTheGpuClearBetweenThem) { if (!Ready()) return; std::vector boxes; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PersistentCoherentMapScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PersistentCoherentMapScenario.cpp index 16cae3f8..d2650619 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PersistentCoherentMapScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PersistentCoherentMapScenario.cpp @@ -102,7 +102,7 @@ void main() { oColor = vec4(vColor, 1.0); } float r, g, b; }; - // A full-viewport quad as two triangles, flat-coloured: one region readback then speaks + // A full-viewport quad as two triangles, flat-colored: one region readback then speaks // for the whole draw, and an offender pixel is a real disagreement rather than an // interpolation difference between two drivers. std::array Quad(float r, float g, float b) { @@ -415,7 +415,7 @@ void main() { oColor = vec4(vColor, 1.0); } EXPECT_TRUE(WholeSurfaceIs(afterSecond, "red", "the SECOND write through the same mapping, announced by nothing: " "this is exit gate E3(b), and a 'push on the next explicit buffer " - "operation' implementation reads back the FIRST write's colour here")); + "operation' implementation reads back the FIRST write's color here")); // E3(d) again, AFTER the draws: b1-v1.md 4.1 item 5 asks that the arm hold across the // whole scenario, not only at the map. A late adoption - the owner declining once and // minting on a later validate point - would leave the first assertion true and this one diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PipeVerifyArmingScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PipeVerifyArmingScenario.cpp index 847abb0d..888ec33a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PipeVerifyArmingScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PipeVerifyArmingScenario.cpp @@ -44,7 +44,7 @@ // fopen(path, "w") at the first log write of a process (MG_Util/Debug/Log.cpp, InitFile), so each // process TRUNCATES it. That is fine for one process and false for many: in the ambient Verify. // lane, 400-odd sibling entries share the one MOBILEGL_LOG_FILE_PATH, and CI runs that lane with -// `ctest -j 4`, so a neighbour's bring-up can truncate the file between this case's draw and its +// `ctest -j 4`, so a neighbor's bring-up can truncate the file between this case's draw and its // read. Every existing scenario in this suite that reads the library log (UnlocatedIoBlockScenario, // the primgen reroute, the point-size demotion) is registered in a FILTERED lane with a log path of // its own for exactly that reason, and this case now follows them: it runs in the VerifyArming. @@ -210,7 +210,7 @@ void main() { o_color = vec4(0.25, 0.5, 0.75, 1.0); } "lane, which owns a log path no other entry writes to. In the ambient " "Verify. lane 400-odd entries share one path and each truncates it " "(Log.cpp opens it \"w\"), so a whole-file read here would race a " - "neighbour under ctest -j 4. Set by the ctest entry, never by hand."; + "neighbor under ctest -j 4. Set by the ctest entry, never by hand."; } if (AmbientQuirkFromEnvironment("MOBILEGL_PIPE_VERIFY") != AmbientQuirk::On) { GTEST_SKIP() << "this case needs MOBILEGL_PIPE_VERIFY=1 for the whole process, which is " diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PipelineFailureScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PipelineFailureScenario.cpp index 37accaff..7c1ff523 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PipelineFailureScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PipelineFailureScenario.cpp @@ -109,7 +109,7 @@ void main() { glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(0)); glBindVertexArray(0); - // A solid red 2x2 texture, so the sampled colour is the same wherever the + // A solid red 2x2 texture, so the sampled color is the same wherever the // (deliberately degenerate) coordinates land. const unsigned char red[] = {255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255}; glGenTextures(1, &m_texture); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PixelStoreSweepScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PixelStoreSweepScenario.cpp index d5b2ae49..24c3d2ee 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PixelStoreSweepScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PixelStoreSweepScenario.cpp @@ -20,7 +20,7 @@ // came back with someone else's pixels - which is what made ~1,500 otherwise-correct cases fail // depending only on how much ran before them. The unit-level pin for the missing destructors is // MG_Test/SanityTest.cpp (DirectGLESBackendFramebuffer/Renderbuffer/Sampler); this file pins the -// end-to-end behaviour they protect. +// end-to-end behavior they protect. // // The mode sweep is the second half of the same story: 46 modes are set and reset per case, so a // mode that fails to restore is indistinguishable from the leak in a full-batch CTS run. The @@ -76,7 +76,7 @@ namespace MGITest { // The CTS table verbatim (glcPackedPixelsTests.cpp VariedRectangleTest::iterate): 32 // common cases plus the 14 core-only ones ES has no equivalent for and MobileGL therefore - // honours on the CPU. IMAGE_WIDTH_1/2 and IMAGE_HEIGHT_1/2 are the CTS's 10 and 15. + // honors on the CPU. IMAGE_WIDTH_1/2 and IMAGE_HEIGHT_1/2 are the CTS's 10 and 15. struct SweepCase { GLenum mode; GLint value; @@ -332,7 +332,7 @@ namespace MGITest { static_assert(kStride == 24, "the alignment round-up must actually round"); static_assert(kFirst == 48, "the skips and the buffer offset must all move the first pixel"); - // Four distinct opaque colours, so a row or a pixel landing in the wrong place is a + // Four distinct opaque colors, so a row or a pixel landing in the wrong place is a // wrong VALUE and not just a wrong offset. const std::uint8_t texels[kW * kH * kBpp] = { 0x11, 0x22, 0x33, 0xFF, 0x44, 0x55, 0x66, 0xFF, 0x77, 0x88, 0x99, 0xFF, 0xAA, 0xBB, 0xCC, 0xFF, diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PoisonOmissionScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PoisonOmissionScenario.cpp index 88a83cf3..60a1d771 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PoisonOmissionScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PoisonOmissionScenario.cpp @@ -369,7 +369,7 @@ void main() { o_color = vec4(0.25, 0.5, 0.75, 1.0); } static std::string DescribeStatus(int status) { if (WIFEXITED(status)) return "exited with status " + std::to_string(WEXITSTATUS(status)); if (WIFSIGNALED(status)) return "died on signal " + std::to_string(WTERMSIG(status)); - return "ended in an unrecognised way"; + return "ended in an unrecognized way"; } #endif }; @@ -470,7 +470,7 @@ void main() { o_color = vec4(0.25, 0.5, 0.75, 1.0); } #if MOBILEGL_BUILD_DISAGGREGATED // WHICH ROLE, for the split pair (P7 wave 3, V1). The union above answers "did the // poison fire", which is all a one-role build can be asked; this pair exists to prove - // that the SERVER'S OWN verb stamp honours the omission + // that the SERVER'S OWN verb stamp honors the omission // (MG_Backend/MGPipe/PipeInputs.cpp's MGPipeServerSetPoisonOmission) - the thing that was // NOT true before wave 3 and made the control silently green. A client-side firing would // satisfy the union and prove the opposite of what the entry claims, so the half is @@ -480,7 +480,7 @@ void main() { o_color = vec4(0.25, 0.5, 0.75, 1.0); } << "the child aborted with " << expectedFatal << ", but NOT in its server-role log. " "This pair is the split arm's control and its whole claim is that the stamp the " - "SERVER writes at the verb boundary honours the omission - a firing anywhere " + "SERVER writes at the verb boundary honors the omission - a firing anywhere " "else means the withheld stamp was the client's and the server-side half is " "untested. Client half:\n" << halves.Client << "\nServer half:\n" diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PostLinkAttachScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PostLinkAttachScenario.cpp index f7582405..811adf2f 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PostLinkAttachScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PostLinkAttachScenario.cpp @@ -79,7 +79,7 @@ void main() } )"; - // The replacement fragment stage of the last case. A different colour, so "which + // The replacement fragment stage of the last case. A different color, so "which // executable did this draw run" is answerable from the frame alone. const char* const kBlueFragmentSource = R"(#version 330 core out vec4 fragColor; @@ -133,7 +133,7 @@ void main() glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); m_target = MakeColorFbo(kFboWidth, kFboHeight); - ASSERT_NE(m_target.fbo, 0u) << "could not create the scenario's colour target"; + ASSERT_NE(m_target.fbo, 0u) << "could not create the scenario's color target"; BindFbo(m_target); DrainErrors(); } @@ -196,7 +196,7 @@ void main() } // Clears to red, draws the full-viewport triangle, and hands back the frame. Red - // is deliberately the clear colour: a draw that silently did not execute leaves a + // is deliberately the clear color: a draw that silently did not execute leaves a // red target, which is a different failure message from a draw that executed and // painted the wrong thing. // @@ -211,8 +211,8 @@ void main() return ReadPixels(kFboWidth, kFboHeight); } - // The clear colour is red and no shader here ever writes red, so "still red" reads - // as "the draw did not execute" and any other wrong colour as "it executed against + // The clear color is red and no shader here ever writes red, so "still red" reads + // as "the draw did not execute" and any other wrong color as "it executed against // the wrong modules" - two failures worth telling apart. static void ExpectFullyColored(const Image& frame, const Rgba8& expected, const char* what) { ASSERT_FALSE(frame.Empty()) << what << ": nothing was read back"; @@ -283,7 +283,7 @@ void main() // modules the draw in that window ran. Between the detach+attach and the relink the // program has three attached shaders and two modules, and GL 4.6 core 7.3 says the // executable is still the one the last link produced - so the frame must come out in - // the OLD fragment shader's colour, not the newly attached one's and not garbage. + // the OLD fragment shader's color, not the newly attached one's and not garbage. // // This is also the other direction of the fix, so it cannot be "freeze the backend on // the first link": the relink really does swap the executable, and the very next draw diff --git a/MobileGL/MG_IntegrationTest/Scenarios/PrimitiveRestartScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/PrimitiveRestartScenario.cpp index 37f50f10..b3b19622 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/PrimitiveRestartScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/PrimitiveRestartScenario.cpp @@ -16,7 +16,7 @@ // // So the first thing this asserts is simply that the process is still here. The second is that // the restart actually happened: the substitution rewrites the index data so the driver restarts -// where the application asked, and the difference between "restart honoured" and "restart +// where the application asked, and the difference between "restart honored" and "restart // silently dropped" is a triangle strip that welds its two halves together across the gap. // // Needs a real context on purpose. The GPU-free suite cannot reach a backend at all, and this is @@ -64,7 +64,7 @@ void main() // // The spares exist so the restart index is a LEGAL vertex index: if the restart were // dropped the driver would still fetch a real vertex rather than read out of bounds, so - // the negative case is defined behaviour and the test measures the restart rather than + // the negative case is defined behavior and the test measures the restart rather than // whatever robust-buffer-access does. constexpr GLfloat kVertices[] = { -0.9f, -0.9f, // 0 - left triangle @@ -78,7 +78,7 @@ void main() }; constexpr GLuint kRestartIndex = 7; - // A triangle STRIP, restarted in the middle: honoured, it is exactly the two triangles + // A triangle STRIP, restarted in the middle: honored, it is exactly the two triangles // above. Dropped, the strip welds vertices 2, 7 and 3 into extra triangles that spill // across the gap - which is what the middle probe below catches. constexpr GLuint kIndices[] = {0, 1, 2, kRestartIndex, 3, 4, 5}; @@ -116,7 +116,7 @@ void main() glViewport(0, 0, kSurface, kSurface); m_program = BuildProgram(); - ASSERT_NE(m_program, 0u) << "the flat-colour program did not build: " << m_buildLog; + ASSERT_NE(m_program, 0u) << "the flat-color program did not build: " << m_buildLog; glUseProgram(m_program); DrainErrors(); } diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ProgramPipelineScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ProgramPipelineScenario.cpp index 451dd486..177cfd87 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ProgramPipelineScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ProgramPipelineScenario.cpp @@ -456,7 +456,7 @@ void main() { o_color = u_color; } // // Runs on both backends. glShaderStorageBlockBinding is a GL 4.3 entry point with no ES // equivalent - ES fixes a storage block's binding at link from its layout(binding=) - // qualifier - so Espryt honours a rebinding by writing the effective binding into the ESSL + // qualifier - so Espryt honors a rebinding by writing the effective binding into the ESSL // it generates (the Binding decoration is rewritten before SPIRV-Cross emits, and the draw // path rebuilds a program whose override set has moved). TEST_F(ProgramPipelineScenario, AStorageBlockRebindingHoldsWithoutAPipeline) { @@ -553,7 +553,7 @@ void main() { o_color = vec4(1.0); } const int height = gl.Height(); static const char* kUniformBlockFS = R"(#version 430 core -layout(std140) uniform Colour { vec4 u_colour; }; +layout(std140) uniform Color { vec4 u_colour; }; out vec4 o_color; void main() { o_color = u_colour; } )"; @@ -562,7 +562,7 @@ void main() { o_color = u_colour; } if (vs == 0 || fs == 0) return; constexpr GLuint kBinding = 3; // not the default 0 the declaration implies - const GLuint blockIndex = glGetUniformBlockIndex(fs, "Colour"); + const GLuint blockIndex = glGetUniformBlockIndex(fs, "Color"); ASSERT_NE(blockIndex, GL_INVALID_INDEX); glUniformBlockBinding(fs, blockIndex, kBinding); ASSERT_EQ(FirstGLError(), 0u) << "glUniformBlockBinding on a separable program errored"; @@ -698,7 +698,7 @@ void main() { o_color = vec4(0.0, 1.0, 0.0, u_mvp[3][3]); } const int height = gl.Height(); static const char* kUniformBlockFS = R"(#version 430 core -layout(std140) uniform Colour { vec4 u_colour; }; +layout(std140) uniform Color { vec4 u_colour; }; out vec4 o_color; void main() { o_color = u_colour; } )"; @@ -706,7 +706,7 @@ void main() { o_color = u_colour; } const GLuint fs = MakeSeparable(GL_FRAGMENT_SHADER, kUniformBlockFS); if (vs == 0 || fs == 0) return; - // Two buffers on two different binding points, holding two different colours. + // Two buffers on two different binding points, holding two different colors. const GLfloat red[4] = {1.0f, 0.0f, 0.0f, 1.0f}; const GLfloat green[4] = {0.0f, 1.0f, 0.0f, 1.0f}; constexpr GLuint kFirstBinding = 2; @@ -721,7 +721,7 @@ void main() { o_color = u_colour; } glBindBufferBase(GL_UNIFORM_BUFFER, kSecondBinding, buffers[1]); glBindBuffer(GL_UNIFORM_BUFFER, 0); - const GLuint blockIndex = glGetUniformBlockIndex(fs, "Colour"); + const GLuint blockIndex = glGetUniformBlockIndex(fs, "Color"); ASSERT_NE(blockIndex, GL_INVALID_INDEX); glUniformBlockBinding(fs, blockIndex, kFirstBinding); @@ -744,7 +744,7 @@ void main() { o_color = u_colour; } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); const Image first = ReadPixels(width, height); EXPECT_TRUE(RegionIsMostly(first, 2, width - 3, 2, height - 3, "red", 0.0, - "the first pipeline draw, with Colour on binding 2")); + "the first pipeline draw, with Color on binding 2")); ASSERT_EQ(FirstGLError(), 0u) << "the first uniform-block pipeline draw leaked a GL error"; // Move the block to the other binding point, with the composite already built and cached. @@ -756,7 +756,7 @@ void main() { o_color = u_colour; } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); const Image second = ReadPixels(width, height); EXPECT_TRUE(RegionIsMostly(second, 2, width - 3, 2, height - 3, "green", 0.0, - "the second pipeline draw, after Colour was rebound to binding 5")); + "the second pipeline draw, after Color was rebound to binding 5")); EXPECT_EQ(FirstGLError(), 0u) << "the rebound uniform-block pipeline draw leaked a GL error"; glBindVertexArray(0); @@ -785,7 +785,7 @@ void main() { o_color = texture(u_tex, vec2(0.5)); } const GLuint fs = MakeSeparable(GL_FRAGMENT_SHADER, kSamplerFS); if (vs == 0 || fs == 0) return; - // One texture per unit, each a different solid colour, so the pixels say which unit the + // One texture per unit, each a different solid color, so the pixels say which unit the // draw actually sampled. constexpr int kUnits = 4; const GLubyte colours[kUnits][4] = {{255, 0, 0, 255}, {0, 255, 0, 255}, {0, 0, 255, 255}, {255, 255, 0, 255}}; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/RelinkStageSetScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/RelinkStageSetScenario.cpp index fbd39a64..5012d1f7 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/RelinkStageSetScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/RelinkStageSetScenario.cpp @@ -17,7 +17,7 @@ // DirectGLES rebuilds its driver program in place - same GL name, new executable - and the // per-draw bind dedupes on that name, so a relink that changed the stage set installed // nothing and the following draws rendered NOTHING at all: no GL error, LINK_STATUS true, -// and a framebuffer that kept its clear colour. See the note at the glLinkProgram in +// and a framebuffer that kept its clear color. See the note at the glLinkProgram in // BackendProgramObjectImpl::SyncToBackend for what the driver does with such a relink. // // PostLinkAttachScenario pins the other half of the same rule - that the executable does @@ -70,7 +70,7 @@ void main() } )"; - // Halves the triangle instead of passing it through: the centre pixel stays covered + // Halves the triangle instead of passing it through: the center pixel stays covered // and all four corners fall outside, so the frame alone says whether this stage ran. const char* const kGeometrySource = R"(#version 420 core layout(triangles) in; @@ -114,7 +114,7 @@ void main() glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); m_target = MakeColorFbo(kFboWidth, kFboHeight); - ASSERT_NE(m_target.fbo, 0u) << "could not create the scenario's colour target"; + ASSERT_NE(m_target.fbo, 0u) << "could not create the scenario's color target"; BindFbo(m_target); DrainErrors(); } @@ -204,7 +204,7 @@ void main() return true; } - // Clears to red and draws. Red is the clear colour deliberately: nothing here ever + // Clears to red and draws. Red is the clear color deliberately: nothing here ever // paints red inside the triangle, so a frame that is red where it should be green // says "this draw did not execute" while a frame that is green where it should be // red says "it executed against the wrong executable" - two failures worth telling @@ -222,7 +222,7 @@ void main() // The vertex stage's triangle covers the whole target, corners included. static void ExpectFullTriangle(const Image& frame, const char* what) { ASSERT_FALSE(frame.Empty()) << what << ": nothing was read back"; - ExpectPixel(frame, kFboWidth / 2, kFboHeight / 2, kGreen, what, "centre"); + ExpectPixel(frame, kFboWidth / 2, kFboHeight / 2, kGreen, what, "center"); for (const int y : {0, kFboHeight - 1}) { for (const int x : {0, kFboWidth - 1}) { ExpectPixel(frame, x, y, kGreen, what, "corner"); @@ -234,7 +234,7 @@ void main() // them, which is what makes the shape readable as "that stage ran". static void ExpectHalvedTriangle(const Image& frame, const char* what) { ASSERT_FALSE(frame.Empty()) << what << ": nothing was read back"; - ExpectPixel(frame, kFboWidth / 2, kFboHeight / 2, kGreen, what, "centre"); + ExpectPixel(frame, kFboWidth / 2, kFboHeight / 2, kGreen, what, "center"); for (const int y : {0, kFboHeight - 1}) { for (const int x : {0, kFboWidth - 1}) { ExpectPixel(frame, x, y, kRed, what, "corner"); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/RenderbufferBlendFormatScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/RenderbufferBlendFormatScenario.cpp index 8d35cc39..ae78c68a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/RenderbufferBlendFormatScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/RenderbufferBlendFormatScenario.cpp @@ -19,11 +19,11 @@ // // VkFormatProperties for VK_FORMAT_UNDEFINED are all zero, so the probe concluded "not blendable" // and every pipeline for that attachment was built with blendEnable = VK_FALSE - permanently, and -// silently apart from one log line. The source colour then overwrites the destination instead of +// silently apart from one log line. The source color then overwrites the destination instead of // blending with it, which is a wrong PICTURE, not a wrong error code. // // GL_RGB8 is the ordinary shape and is what this scenario leads with: it is a required -// colour-renderable format, its image has been R8G8B8A8_UNORM all along, and the probe asked about +// color-renderable format, its image has been R8G8B8A8_UNORM all along, and the probe asked about // the 24-bit R8G8B8_UNORM that most drivers do not support at all. GL_RGBA4 covers the other half - // a format whose probe answered a real-but-different VkFormat. // @@ -106,7 +106,7 @@ void main() // Returns false (having skipped, not failed) when the driver will not give us a complete // framebuffer for this format - GL only requires a subset of formats to be - // colour-renderable, and the point of the scenario is blending, not format support. + // color-renderable, and the point of the scenario is blending, not format support. bool MakeTarget(GLenum internalFormat) { Destroy(); glGenRenderbuffers(1, &m_renderbuffer); @@ -136,10 +136,10 @@ void main() }; // One draw of opaque black, then a 50%-alpha white draw over it with the ordinary - // SRC_ALPHA / ONE_MINUS_SRC_ALPHA function. Blending gives mid-grey; a pipeline built with + // SRC_ALPHA / ONE_MINUS_SRC_ALPHA function. Blending gives mid-gray; a pipeline built with // blendEnable = VK_FALSE gives white, because the source simply overwrites. // - // The tolerance is wide on purpose: RGBA4 has four bits per channel, so "mid-grey" is one of + // The tolerance is wide on purpose: RGBA4 has four bits per channel, so "mid-gray" is one of // a handful of representable values and the test must not become a quantisation test. void ExpectBlendedRatherThanOverwritten(const char* what) { const Image image = ReadPixels(kExtent, kExtent); @@ -149,13 +149,13 @@ void main() << ", which is darker than a blend of " "black and 50% white"; EXPECT_LT(int(centre.r), 215) - << what << ": got " << centre << ", which is the source colour - blending was disabled"; + << what << ": got " << centre << ", which is the source color - blending was disabled"; } } // namespace // The ordinary case, and the one broken today rather than only after the format table was - // unified: a three-channel colour renderbuffer. Its image has been R8G8B8A8_UNORM all along while + // unified: a three-channel color renderbuffer. Its image has been R8G8B8A8_UNORM all along while // the blend probe asked about R8G8B8_UNORM, which most drivers do not support at all. TEST_F(RenderbufferBlendFormatScenario, BlendingWorksOnAThreeChannelRenderbuffer) { if (!Ready()) GTEST_SKIP(); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ResidentIndexScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ResidentIndexScenario.cpp index 210b39a6..0f82821a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ResidentIndexScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ResidentIndexScenario.cpp @@ -63,7 +63,7 @@ // These cases therefore stay as what they honestly are: end-to-end regression // tests for resident index-buffer freshness across frame boundaries, and the // standing tripwire for change (1). The moment anyone memoises the streamed or -// promoted index path - the natural next step for the same optimisation - these +// promoted index path - the natural next step for the same optimization - these // stop being redundant and start failing. Each case says below what it covers. #include diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ResourceSubsystemControlScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ResourceSubsystemControlScenario.cpp index d60e72af..3128c3ed 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ResourceSubsystemControlScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ResourceSubsystemControlScenario.cpp @@ -33,8 +33,8 @@ // fails: with bit 7 ignored, this arm would report the same non-zero count as the other one. // // both arms -// THE PIXELS MUST NOT MOVE. The arena is filled with one solid-colour quad and drawn, and -// both arms must read back that colour. "The counters moved and the picture did not" is the +// THE PIXELS MUST NOT MOVE. The arena is filled with one solid-color quad and drawn, and +// both arms must read back that color. "The counters moved and the picture did not" is the // whole claim - a switch that changed what is drawn would not be an A/B, it would be a bug. // // WHY IT CAN SKIP. The counter is emitted by the client-side resource tracker (P3a package B), and @@ -310,12 +310,12 @@ void main() { oColor = vec4(vColor, 1.0); } << window.line; } else { FAIL() << "unknown " << kLaneMarker << " value '" << m_lane - << "': the arms are on / off. Reading an unrecognised name as either would make " + << "': the arms are on / off. Reading an unrecognized name as either would make " "this lane assert the other arm's expectation while claiming to test this one."; } // ... and the picture is the same whichever arm ran. The arena is drawn with one solid - // colour, so both arms must read back exactly that. + // color, so both arms must read back exactly that. EXPECT_TRUE(RegionIsMostly(image, kInset, image.Width() - kInset, kInset, image.Height() - kInset, "green", 0.0, "the arena draw [" + m_lane + "]")) << "the subsystem bits changed what is DRAWN, which is not an A/B - the handle path and " diff --git a/MobileGL/MG_IntegrationTest/Scenarios/SampleMaskScopeScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/SampleMaskScopeScenario.cpp index 160f6996..6c8ad043 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/SampleMaskScopeScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/SampleMaskScopeScenario.cpp @@ -27,7 +27,7 @@ // dEQP/GL-CTS multisample cases leave exactly these masks behind. That is the MSAA-then-present // shape every application uses. // -// The cases below are single-sample by construction (the scenario harness's colour FBO), so each +// The cases below are single-sample by construction (the scenario harness's color FBO), so each // one asserts that the mask changed nothing. #include diff --git a/MobileGL/MG_IntegrationTest/Scenarios/SampleVariablesScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/SampleVariablesScenario.cpp index 869f5fa9..79b60de9 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/SampleVariablesScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/SampleVariablesScenario.cpp @@ -48,7 +48,7 @@ void main() { gl_Position = vec4(aPos, 0.0, 1.0); } )"; // gl_NumSamples scaled so each count lands on its own well-separated 8-bit value: 1 -> 16, - // 2 -> 32, 4 -> 64. Every sample of the fragment gets the same colour, so the resolve blit + // 2 -> 32, 4 -> 64. Every sample of the fragment gets the same color, so the resolve blit // averages identical values and the readback is exact rather than approximate. constexpr const char* kFS = R"(#version 400 core out vec4 o_color; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/SampledSetStalenessScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/SampledSetStalenessScenario.cpp index 8fb3df4e..0e0d847e 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/SampledSetStalenessScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/SampledSetStalenessScenario.cpp @@ -21,7 +21,7 @@ // incomplete -> complete under a fixed binding kept being answered out of the memo as "not in the // set", and the work SetupDraw does for the set never happened for it: // -// * its queued clear was never materialised, so the draw sampled pre-clear content - wrong +// * its queued clear was never materialized, so the draw sampled pre-clear content - wrong // pixels, no validation layer needed, which is what the case below detects; and // * its layout transition moved into the descriptor resolve, which records // vkCmdPipelineBarrier inside an already-open render pass whose subpass declares no @@ -170,16 +170,16 @@ void main() { ASSERT_EQ(FirstGLError(), 0u) << "changing the filter raised a GL error"; // 4. Draw again, into the same recording, and only now read back. The texture is in the - // sampled set now, so its queued clear has to be materialised before the pass opens and + // sampled set now, so its queued clear has to be materialized before the pass opens and // the fetch has to see RED. Reading the green the texture was uploaded with means the - // clear was never materialised, i.e. the texture never entered the set - the stale-memo + // clear was never materialized, i.e. the texture never entered the set - the stale-memo // bug. Black means the fallback was still being handed out. DrawOnly(); const Image afterFlip = ReadPixels(kFboSize, kFboSize); ASSERT_FALSE(afterFlip.Empty()) << "the readback came back empty"; EXPECT_TRUE(RegionIsMostly(afterFlip, 0, kFboSize - 1, 0, kFboSize - 1, "red", 0.0, "the draw after the completeness flip")) - << "green means the queued clear was never materialised, so the texture never re-entered " + << "green means the queued clear was never materialized, so the texture never re-entered " "the sampled set after the filter change; blue means the draw did not happen at all"; } @@ -222,7 +222,7 @@ void main() { ASSERT_FALSE(afterFlip.Empty()) << "the readback came back empty"; EXPECT_TRUE(RegionIsMostly(afterFlip, 0, kFboSize - 1, 0, kFboSize - 1, "red", 0.0, "the draw after the sampler-object flip")) - << "green means the queued clear was never materialised after the sampler parameter change"; + << "green means the queued clear was never materialized after the sampler parameter change"; glBindSampler(0, 0); glDeleteSamplers(1, &sampler); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ScenarioIsolationScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ScenarioIsolationScenario.cpp index 727e7de1..06a71431 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ScenarioIsolationScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ScenarioIsolationScenario.cpp @@ -22,7 +22,7 @@ // // The two cases below run in declaration order in ONE process (the // ScenarioIsolationScenario.CasesInOneProcess registrations in CMakeLists.txt). The first one is -// the careless neighbour; the second asserts what ScenarioTest::SetUp owes every case. Each is +// the careless neighbor; the second asserts what ScenarioTest::SetUp owes every case. Each is // green on its own, so the ordinary one-case-per-process entries cannot see the bug. #include @@ -65,7 +65,7 @@ void main() { } // namespace - // The careless neighbour: its program is deleted while current and never unbound, and it + // The careless neighbor: its program is deleted while current and never unbound, and it // leaves an error in the queue that nobody reads. TEST_F(ScenarioIsolationScenario, ACaseLeavesItsDeletedProgramCurrentAndAnErrorUnread) { if (!Ready()) return; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/SnormAttachmentScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/SnormAttachmentScenario.cpp index c51d9bbd..0ed77b3d 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/SnormAttachmentScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/SnormAttachmentScenario.cpp @@ -6,10 +6,10 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header // -// Scenario - SIGNED-NORMALIZED COLOUR ATTACHMENTS, on a live driver. +// Scenario - SIGNED-NORMALIZED COLOR ATTACHMENTS, on a live driver. // // The bug: a GLES driver without GL_EXT_render_snorm treats every signed-normalized format as -// texture-only. DirectGLES had a colour-renderable substitute for exactly one of the eight +// texture-only. DirectGLES had a color-renderable substitute for exactly one of the eight // (GL_RGB16_SNORM, through the three-channel widening), so an R8_SNORM or R16_SNORM attachment got // no storage the driver would render into: the ES framebuffer was incomplete, the draw landed // nowhere, and glGetTexImage fell through to the CPU shadow - all zeroes for a texture created with @@ -27,7 +27,7 @@ // WHAT THIS GATE CAN AND CANNOT SEE. Both CI drivers (llvmpipe) and Adreno expose // GL_EXT_render_snorm, so they take the NATIVE path here and the substitution stays dead. That is // precisely why the assertions are written as invariants of the format rather than of the fallback: -// "a signed-normalized colour attachment is complete and round-trips its channel values" has to +// "a signed-normalized color attachment is complete and round-trips its channel values" has to // hold whichever path answers it, so the scenario fails if anyone ever routes these formats to a // lossy storage on a driver where it IS live. The substitution itself can only be observed on a // device without EXT_render_snorm (Mali Immortalis-G925). @@ -71,7 +71,7 @@ void main() { oColor = vec4(uValue, 0.0, 0.0, 1.0); } // The two channel values the round trip is pinned on. Both are positive on purpose: // glReadPixels applies GL_CLAMP_READ_COLOR (GL_FIXED_ONLY by default) to a fixed-point - // colour buffer, so the negative half of a SNORM attachment reads back as 0 and would + // color buffer, so the negative half of a SNORM attachment reads back as 0 and would // measure the clamp instead of the storage. constexpr int kSnorm8Value = 99; constexpr int kSnorm16Value = 23451; @@ -186,10 +186,10 @@ void main() { oColor = vec4(uValue, 0.0, 0.0, 1.0); } TEST_F(SnormAttachmentScenario, SignedNormalizedColorAttachmentsReportComplete) { if (!Ready() || IsSkipped()) return; - // GL_R8 is the control: colour-renderable in ES core, so it must pass with or without + // GL_R8 is the control: color-renderable in ES core, so it must pass with or without // any substitution. If it ever fails, nothing below means anything. EXPECT_EQ(SingleAttachmentStatus(GL_R8), static_cast(GL_FRAMEBUFFER_COMPLETE)) - << "GL_R8 is ES-core colour-renderable"; + << "GL_R8 is ES-core color-renderable"; // The single-channel pair KHR-GL4x.texture_swizzle renders into for every SNORM source // format - the whole 46-case failure. @@ -215,7 +215,7 @@ void main() { oColor = vec4(uValue, 0.0, 0.0, 1.0); } const float snorm8Expected = static_cast(kSnorm8Value) / 127.0f; float red8 = -1.0f; ASSERT_TRUE(RenderAndReadRed(GL_R8_SNORM, snorm8Expected, &red8)) - << "an R8_SNORM colour attachment must be complete before any value can be asserted"; + << "an R8_SNORM color attachment must be complete before any value can be asserted"; // Two 8-bit SNORM steps. A half float is exact here (worst case 0.03 of a step), so this // only has to catch a storage that quantizes harder than the format itself. EXPECT_NEAR(red8, snorm8Expected, 2.0f / 127.0f) << "R8_SNORM attachment lost its channel value"; @@ -224,7 +224,7 @@ void main() { oColor = vec4(uValue, 0.0, 0.0, 1.0); } const float snorm16Expected = static_cast(kSnorm16Value) / 32767.0f; float red16 = -1.0f; ASSERT_TRUE(RenderAndReadRed(GL_R16_SNORM, snorm16Expected, &red16)) - << "an R16_SNORM colour attachment must be complete before any value can be asserted"; + << "an R16_SNORM color attachment must be complete before any value can be asserted"; // Two 16-bit SNORM steps (6.1e-5). A half float would land 1.9e-4 away - three times // this window - which is exactly the failure this bound exists to catch. EXPECT_NEAR(red16, snorm16Expected, 2.0f / 32767.0f) @@ -233,7 +233,7 @@ void main() { oColor = vec4(uValue, 0.0, 0.0, 1.0); } float red16x4 = -1.0f; ASSERT_TRUE(RenderAndReadRed(GL_RGBA16_SNORM, snorm16Expected, &red16x4)) - << "an RGBA16_SNORM colour attachment must be complete before any value can be asserted"; + << "an RGBA16_SNORM color attachment must be complete before any value can be asserted"; EXPECT_NEAR(red16x4, snorm16Expected, 2.0f / 32767.0f) << "RGBA16_SNORM attachment was stored in something that cannot hold 16 signed bits"; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/SpirvShaderBinaryScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/SpirvShaderBinaryScenario.cpp index 8dff5995..7c7f675c 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/SpirvShaderBinaryScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/SpirvShaderBinaryScenario.cpp @@ -183,7 +183,7 @@ namespace MGITest { if (!Ready()) return; const GLuint shader = glCreateShader(GL_VERTEX_SHADER); - // 0x8DF9 is GL_SHADER_BINARY_FORMATS' neighbour, not a format: any value but + // 0x8DF9 is GL_SHADER_BINARY_FORMATS' neighbor, not a format: any value but // GL_SHADER_BINARY_FORMAT_SPIR_V is GL_INVALID_ENUM. The stub used to return silently. glShaderBinary(1, &shader, 0x8DF9, kVertexModule, sizeof(kVertexModule)); EXPECT_EQ(FirstGLError(), static_cast(GL_INVALID_ENUM)); @@ -277,7 +277,7 @@ namespace MGITest { kScaleConstantId, halfBits, &log); ASSERT_NE(vs, 0u) << "vertex: " << log; // Channel 1 is green; the module's own default is 0 (red), so a specialization that did - // nothing paints the wrong colour. + // nothing paints the wrong color. const unsigned int fs = MakeSpirvShader(GL_FRAGMENT_SHADER, kFragmentModule, sizeof(kFragmentModule) / sizeof(kFragmentModule[0]), kChannelConstantId, 1u, &log); @@ -318,10 +318,10 @@ namespace MGITest { const Image painted = ReadPixels(width, height); const Rgba8 centre = painted.At(width / 2, height / 2); EXPECT_LT(centre.r, 32) << "the fragment module wrote the wrong channel; constant id 7 was not applied"; - EXPECT_GT(centre.g, 224) << "the centre of a 0.5-scaled quad must be painted"; + EXPECT_GT(centre.g, 224) << "the center of a 0.5-scaled quad must be painted"; // A pixel just inside the corner is OUTSIDE the 0.5-scaled quad and must still be the - // clear colour - which is what proves constant id 3 reached the vertex module. At the + // clear color - which is what proves constant id 3 reached the vertex module. At the // default scale of 1.0 the quad covers the whole viewport and this pixel would be green. const Rgba8 corner = painted.At(1, 1); EXPECT_LT(corner.g, 32) << "the quad was not scaled; the vertex specialization constant was not applied"; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/StorageBufferRegrowScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/StorageBufferRegrowScenario.cpp index 7e04efeb..335a38c2 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/StorageBufferRegrowScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/StorageBufferRegrowScenario.cpp @@ -82,7 +82,7 @@ void main() { // Set by the MapPersistentRoundtrips. ctest entry and by nothing else; a harness marker, // never read by the library. Its absence means an ambient entry, where neither the stats // channel nor a private log path is configured - and where the shared log makes a read - // race a neighbour's bring-up. + // race a neighbor's bring-up. constexpr const char* kLaneMarker = "MGITEST_MPR_LANE"; bool BuildMarkerIsSet(const char* name) { @@ -173,7 +173,7 @@ void main() { "MOBILEGL_PIPE_STATS=1, MOBILEGL_PIPE_STATS_PERIOD=1 and a private " "MOBILEGL_LOG_FILE_PATH. None of that is configured in the ambient " "entries, and the ambient log is shared, so a read here would race a " - "neighbour's bring-up."; + "neighbor's bring-up."; return; } if (!BuildMarkerIsSet("MGITEST_PIPE_PUSH_BUILD")) { diff --git a/MobileGL/MG_IntegrationTest/Scenarios/TessellationXfbCaptureScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/TessellationXfbCaptureScenario.cpp index 96c15ca5..4dddf35a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/TessellationXfbCaptureScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/TessellationXfbCaptureScenario.cpp @@ -24,7 +24,7 @@ // evaluation stage and only then captured. This is the shape of // KHR-GL4x.tessellation_shader.tessellation_control_to_tessellation_evaluation. // gl_MaxPatchVertices_Position_PointSize, which is 216 of the ~240 conformance bodies -// the family still fails: gl_Position arrives, and everything travelling beside it in +// the family still fails: gl_Position arrives, and everything traveling beside it in // the same patch does not. // // The assertions are on the captured BYTES against a CPU-computed reference, never on the @@ -509,7 +509,7 @@ void main() // The reduced conformance body. `withPointSize` selects between its two halves; // everything else - one input vertex, an output patch of GL_MAX_PATCH_VERTICES, a - // user per-vertex block travelling beside gl_PerVertex, the capture taken off the + // user per-vertex block traveling beside gl_PerVertex, the capture taken off the // evaluation stage - is the same on both. void TessellationXfbCaptureScenario::RunPerVertexPayloadCase(bool withPointSize) { if (!Ready()) GTEST_SKIP(); @@ -779,7 +779,7 @@ void main() EXPECT_EQ(glGetError(), GL_NO_ERROR); } - // The same patch with gl_PointSize travelling in gl_PerVertex beside gl_Position. + // The same patch with gl_PointSize traveling in gl_PerVertex beside gl_Position. // In ESSL gl_PointSize does not EXIST in a tessellation stage unless // GL_EXT_tessellation_point_size is requested, so a backend that lowers to ESSL // without asking for it does not merely lose the value - the stage fails to compile diff --git a/MobileGL/MG_IntegrationTest/Scenarios/TextureParamsWithoutASamplerViewScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/TextureParamsWithoutASamplerViewScenario.cpp index 8cc8281c..673577cc 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/TextureParamsWithoutASamplerViewScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/TextureParamsWithoutASamplerViewScenario.cpp @@ -9,10 +9,11 @@ // Scenario - A TEXTURE'S PARAMETERS TAKE EFFECT EVEN WHEN IT HAS NO SAMPLER VIEW (gate G9), the // one scenario the acceptance gate names by hand and requires to be RED before P4a lands. // -// THE DESIGN STATEMENT IT TESTS, ARCHITECTURE.md §3.2 (D10), verbatim: "SetTextureParams 按资源寻址、 -// 与 sampler view 分开(D10):只作 FBO attachment / image 单元 / glCopyImageSubData 端点的纹理没有 -// sampler view,但 Espryt 对 attachment 也同步纹理参数,且 RequireImageBindableStorage 需要在前端参数 -// 版本不动时强制重同步." A texture that is only an attachment, only an image-unit binding or only a +// THE DESIGN STATEMENT IT TESTS, ARCHITECTURE.md §3.2 (D10), verbatim: "SetTextureParams addresses by resource, +// separately from the sampler view (D10): a texture used only as an FBO attachment / image unit / +// glCopyImageSubData endpoint has no sampler view, but Espryt also synchronizes texture parameters +// for attachments, and RequireImageBindableStorage must force a resync when the frontend parameter +// version has not moved." A texture that is only an attachment, only an image-unit binding or only a // copy endpoint has NO sampler view at all - so a design that carried texture parameters on the // view would silently drop them for exactly those textures. P4a addresses set_texture_params by // RESOURCE, independently of any binding, which is what makes the record exist for every texture @@ -48,7 +49,7 @@ // in particular they would go RED if any of the four reachability paths were ever made to // depend on the texture having a sampler VIEW - which is exactly the coupling P4a's // resource-addressed set_texture_params removes and the thing a later phase could reintroduce; -// * the "must be red before landing" artefact the acceptance gate asks for is NOT produced by the public-GL half +// * the "must be red before landing" artifact the acceptance gate asks for is NOT produced by the public-GL half // of this file, and no public-GL integration scenario on a monolith tree can produce it. // Producing it needs an observation of the DRIVER's texture object taken while the texture is // still read-attachment-only. ID-19 rules that G9 is therefore a WHITE-BOX assertion, and this @@ -109,7 +110,7 @@ // so a texture that is exclusively a READ attachment gets its STORAGE synced // and its PARAMETERS never. P4a closes that gap deliberately (D-E3): the record is addressed by // resource, and Espryt's SyncAttachmentObject applies parameters for ANY attachment, draw or read. -// It is a behaviour change and it is the deliverable, not a drive-by dev fix (guide/discipline.md). +// It is a behavior change and it is the deliverable, not a drive-by dev fix (guide/discipline.md). // // HOW EACH CASE OBSERVES "REACHED THE DRIVER", and why the observation is always a LATER SAMPLE. // A texture parameter is by definition a sampling parameter: nothing about an attachment, an image @@ -120,7 +121,7 @@ // 2. move a parameter while it is reachable ONLY that way (through the DSA entry points // glTextureParameteri / glTextureSubImage2D, so no step of the setup ever binds the texture to // a sampler unit - a bind would put it on the unit list and answer the question by accident), -// 3. sample it once, at the end, and read the colour back. +// 3. sample it once, at the end, and read the color back. // // - and the difference between them is step 1 alone. A case that is red says: the parameter set // while the texture was reachable only that way did not survive to the sample. @@ -164,7 +165,7 @@ void main() { )"; // Samples texel (0,0) with an explicit fetch: no filtering, no derivatives, no wrap - so - // the colour that comes back is the texel as the driver's swizzle presents it and nothing + // the color that comes back is the texel as the driver's swizzle presents it and nothing // else can move it. constexpr const char* kFetchFS = R"(#version 330 core uniform sampler2D uTex; @@ -174,7 +175,7 @@ void main() { oColor = texelFetch(uTex, ivec2(0, 0), 0); } // The stencil aspect of a packed depth/stencil texture is an UNSIGNED INTEGER texture, so // it needs a usampler2D. The case that uses it turns "the stencil value is what was - // cleared" into a colour, because a colour is the only thing this harness can read back. + // cleared" into a color, because a color is the only thing this harness can read back. constexpr const char* kStencilFetchFS = R"(#version 330 core uniform usampler2D uTex; uniform uint uExpected; @@ -255,7 +256,7 @@ void main() { } } - // A 4x4 RGBA8 texture, one solid colour, created and filled WITHOUT EVER BINDING IT. + // A 4x4 RGBA8 texture, one solid color, created and filled WITHOUT EVER BINDING IT. GLuint MakeSolidTextureWithoutBinding(std::uint8_t r, std::uint8_t g, std::uint8_t b) { std::vector texels(kTextureSize * kTextureSize * 4); for (std::size_t i = 0; i < texels.size(); i += 4) { @@ -299,7 +300,7 @@ void main() { } // R -> ZERO and G -> ONE, so a RED texel samples as GREEN if and only if the swizzle - // reached the driver, and as RED if it did not. Two colours the harness can name, from + // reached the driver, and as RED if it did not. Two colors the harness can name, from // one parameter change, with no third outcome that could be mistaken for either. void SwizzleRedIntoGreen(GLuint texture) { glTextureParameteri(texture, GL_TEXTURE_SWIZZLE_R, GL_ZERO); @@ -757,7 +758,7 @@ void main() { "(the swizzle reached the driver); RED means the copy landed and the swizzle did " "not; BLUE means neither happened, i.e. the destination is still its own original " "texel and glCopyImageSubData wrote nothing. The swizzle is what turns any texel " - "into (0,1,0), so the colour separates the two failures rather than merging them."; + "into (0,1,0), so the color separates the two failures rather than merging them."; GLuint cleanup[2] = {source, destination}; glDeleteTextures(2, cleanup); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/TextureUploadShapeScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/TextureUploadShapeScenario.cpp index cf7d6ee8..c99cf57d 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/TextureUploadShapeScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/TextureUploadShapeScenario.cpp @@ -28,7 +28,7 @@ // decides the shape for a texture uploaded through a VIEW - is the next phase's", and gating a // shape the phase had not finished deciding would have pinned a non-answer. THAT WORK LANDED: // the cursor is keyed on the storage owner (TextureEmit.h's drain list), the remap is -// TextureObjectView::ToOwner*, and TextureViewAliasScenario is its behavioural gate. So the +// TextureObjectView::ToOwner*, and TextureViewAliasScenario is its behavioral gate. So the // numbers are no longer provisional and the RecordProperty block became EXPECT_EQ against the // table below. // diff --git a/MobileGL/MG_IntegrationTest/Scenarios/TextureViewAliasScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/TextureViewAliasScenario.cpp index 33c3a6e7..3325b469 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/TextureViewAliasScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/TextureViewAliasScenario.cpp @@ -6,8 +6,8 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header // -// Scenario - THE OWNER-KEYED EMISSION CURSOR (P3b/P4b, wave 2-D; ROADMAP's "dirty 归属反转 - -// 按存储属主键控的发射游标"). THE VERIFICATION HALF. +// Scenario - THE OWNER-KEYED EMISSION CURSOR (P3b/P4b, wave 2-D; ROADMAP's "dirty ownership inversion - +// an emission cursor keyed on the storage owner"). THE VERIFICATION HALF. // // THE CODE HALF ALREADY LANDED and this file is the gate it never had: // @@ -30,8 +30,8 @@ // That is exactly the shape SSIM and every ordinary pixel case go green over. // // SO THE CLAIM IS ASSERTED ON BOTH CHANNELS AT ONCE, and neither alone is the gate -// (7.3, "门:新增场景,通过 view 上传、经属主采样(以及反 -// 向),跨 draw 边界各一次"): +// (7.3, "gate: a new scenario that uploads through a view, samples through the owner +// (and the reverse), once each across a draw boundary"): // // PIXELS an upload through one name must be visible through the other name, in the SAME // frame it was issued - and the layers the view does not address must not move. @@ -295,7 +295,7 @@ void main() { oColor = texture(uTex, vec3(vUv, float(uLayer))); } } // Whole-region rather than a spot check, for the reason HeadlessGL.h gives: three of - // four vertices carrying stale data still paints a correct centre pixel. + // four vertices carrying stale data still paints a correct center pixel. void ExpectWholeSurface(const Image& image, Rgba8 expected, const char* what) { int offenders = 0; Rgba8 firstOffender{}; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/TextureViewScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/TextureViewScenario.cpp index cbe353ec..9a35efa3 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/TextureViewScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/TextureViewScenario.cpp @@ -249,7 +249,7 @@ void main() { glDrawArrays(GL_TRIANGLES, 0, 6); } - // Reads the colour texture currently attached to `fbo` as COLOR_ATTACHMENT0. + // Reads the color texture currently attached to `fbo` as COLOR_ATTACHMENT0. Image ReadFbo(GLuint fbo, int width, int height) { glBindFramebuffer(GL_FRAMEBUFFER, fbo); glReadBuffer(GL_COLOR_ATTACHMENT0); @@ -258,7 +258,7 @@ void main() { // Every pixel of the inclusive region must match `expected` within `tolerance` per // channel. Whole-region rather than a spot check, for the reason HeadlessGL.h gives: - // three of four vertices carrying stale data still paints a correct centre pixel. + // three of four vertices carrying stale data still paints a correct center pixel. void ExpectRegion(const Image& image, int x0, int x1, int y0, int y1, Rgba8 expected, int tolerance, const char* what) { int offenders = 0; @@ -400,7 +400,7 @@ void main() { glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); - // The mod's own indexed/non-indexed colour-mask pair (OpenGLRenderer.java:411-412). + // The mod's own indexed/non-indexed color-mask pair (OpenGLRenderer.java:411-412). glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -490,7 +490,7 @@ void main() { // GL_RGBA8 and GL_R32UI are both VIEW_CLASS_32_BITS, so one may be viewed as the // other. Filling the RGBA8 storage with a known byte pattern makes the R32UI view's - // answer a fact about the BITS rather than about the colour. + // answer a fact about the BITS rather than about the color. const GLuint storage = MakeImmutable2D(GL_RGBA8, 1, kSize, kSize); std::vector texels(static_cast(kSize) * kSize * 4); for (std::size_t i = 0; i < texels.size(); i += 4) { @@ -532,7 +532,7 @@ void main() { // A REAL GL_R32UI texture holding the very word the storage's bytes spell. The // assertion below is that the view and this texture sample IDENTICALLY. // - // Comparing against a reference texture rather than against a hard-coded colour is + // Comparing against a reference texture rather than against a hard-coded color is // deliberate. Sampling a 32-bit integer texture is not itself what this scenario is // about, and llvmpipe's ES driver does it inconsistently (verified outside MobileGL, // with a raw-EGL program that reproduces the same wrong decode with NO view in play). @@ -586,8 +586,8 @@ void main() { } EXPECT_EQ(mismatches, 0u) << "the GL_R32UI view of GL_RGBA8 storage must sample exactly what a real GL_R32UI texture " - "holding the same word does; view centre is " - << Describe(throughView.At(kSize / 2, kSize / 2)) << ", reference centre is " + "holding the same word does; view center is " + << Describe(throughView.At(kSize / 2, kSize / 2)) << ", reference center is " << Describe(referenceTexel); DestroyColorFbo(destination); } @@ -654,7 +654,7 @@ void main() { glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); ASSERT_EQ(glGetError(), static_cast(GL_NO_ERROR)); - // A different colour per layer, so a view that lost its layer offset reads the wrong + // A different color per layer, so a view that lost its layer offset reads the wrong // one rather than merely reading nothing. const GLuint seedFbo = MakeFbo(); glBindFramebuffer(GL_FRAMEBUFFER, seedFbo); @@ -940,8 +940,8 @@ void main() { constexpr int kViewNumLevels = 3; constexpr int kViewMinLayer = 1; constexpr int kViewNumLayers = 2; - // One colour per level, so a level that was redefined from the view's base extent reads - // as another level's colour rather than as a plausible one. + // One color per level, so a level that was redefined from the view's base extent reads + // as another level's color rather than as a plausible one. const Rgba8 levelColour[kLevels] = { {255, 0, 0, 255}, {0, 0, 255, 255}, {255, 255, 0, 255}, {255, 0, 255, 255}, {0, 255, 255, 255}}; @@ -974,7 +974,7 @@ void main() { glTextureParameteri(view, GL_TEXTURE_MAX_LEVEL, 2); // The generation's source is the view's base level, the owner's level 2. Writing it in - // GREEN on the GPU gives the source and the level generated from it the same colour, so + // GREEN on the GPU gives the source and the level generated from it the same color, so // losing either one is visible below. const GLuint fbo = MakeFbo(); glBindFramebuffer(GL_FRAMEBUFFER, fbo); @@ -1060,8 +1060,8 @@ void main() { constexpr int kViewMinLayer = 1; constexpr int kViewNumLayers = 2; constexpr std::uint8_t kCanaryByte = 0xAB; - // One colour per storage layer, so a lost layer origin and a read past the window are - // both visible as another layer's colour rather than as a plausible one. + // One color per storage layer, so a lost layer origin and a read past the window are + // both visible as another layer's color rather than as a plausible one. const auto layerColour = [](int layer) { return Rgba8{static_cast(10 * (layer + 1)), 40, 7, 255}; }; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ThreeChannelAttachmentScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ThreeChannelAttachmentScenario.cpp index cf54dd3b..1ecaf48a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ThreeChannelAttachmentScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ThreeChannelAttachmentScenario.cpp @@ -6,11 +6,11 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header // -// Scenario - THREE-CHANNEL COLOUR ATTACHMENTS, on a live driver. +// Scenario - THREE-CHANNEL COLOR ATTACHMENTS, on a live driver. // // The bug: no OpenGL ES driver renders to a three-channel image. EXT_render_snorm covers // R/RG/RGBA only, EXT_color_buffer_float excludes RGB16F, and RGB integer formats are not -// colour-renderable anywhere. Complementary Reimagined declares colortex1 = RGB8_SNORM and +// color-renderable anywhere. Complementary Reimagined declares colortex1 = RGB8_SNORM and // colortex2 = RGB16F, so every framebuffer Iris built from them answered // GL_FRAMEBUFFER_UNSUPPORTED and Iris refused to load the shaderpack. DirectGLES now stores such // an attachment in its four-channel sibling (GL_RGB8_SNORM -> GL_RGBA16F) and reports the @@ -18,12 +18,12 @@ // // WHY THIS SCENARIO EXISTS RATHER THAN A UNIT TEST. The unit tests in // MG_Test/Framebuffer/FramebufferTest.cpp drive a HAND-BUILT capability cache: they prove the -// frontend accepts a caveat capability, and prove the colour-mask/clear discipline that keeps a +// frontend accepts a caveat capability, and prove the color-mask/clear discipline that keeps a // widened attachment's stored alpha at 1.0, but they cannot prove that a real driver's probe // actually PRODUCES that caveat. Only a live glCheckFramebufferStatus can, and the answer is // per-driver, not per-platform: // -// llvmpipe (the headless CI driver), ES 3.2, GL_TEXTURE_2D colour attachment: +// llvmpipe (the headless CI driver), ES 3.2, GL_TEXTURE_2D color attachment: // COMPLETE GL_RGB8, GL_RGB16F, GL_R11F_G11F_B10F, every RGBA* // INCOMPLETE_ATTACHMENT GL_RGB8_SNORM, GL_SRGB8, every RGB integer format // UNSUPPORTED GL_RGB32F @@ -125,10 +125,10 @@ void main() { TEST_F(ThreeChannelAttachmentScenario, ThreeChannelColorAttachmentsReportComplete) { if (!Ready() || IsSkipped()) return; - // GL_RGB8 is the control: colour-renderable in ES core, so it must pass with or + // GL_RGB8 is the control: color-renderable in ES core, so it must pass with or // without any substitution. If it ever fails, nothing below means anything. EXPECT_EQ(SingleAttachmentStatus(GL_RGB8), static_cast(GL_FRAMEBUFFER_COMPLETE)) - << "GL_RGB8 is ES-core colour-renderable"; + << "GL_RGB8 is ES-core color-renderable"; // Complementary Reimagined's colortex1 and colortex2. EXPECT_EQ(SingleAttachmentStatus(GL_RGB8_SNORM), static_cast(GL_FRAMEBUFFER_COMPLETE)) @@ -148,7 +148,7 @@ void main() { // The other half: the substitution has to be INVISIBLE. A three-channel format has no // alpha, so GL answers 1.0 for it - and that answer has to hold after a draw that wrote // something else into the widened storage's real alpha channel, which is what the - // colour-mask discipline in SyncRenderState is for. GL_DST_ALPHA blending and + // color-mask discipline in SyncRenderState is for. GL_DST_ALPHA blending and // glBlitFramebuffer read that stored alpha inside the driver, where no readback fixup can // reach it, so "the storage really holds 1.0" is the only workable invariant. TEST_F(ThreeChannelAttachmentScenario, WidenedAttachmentReadsBackOpaqueWhileItsNeighbourKeepsItsAlpha) { @@ -274,7 +274,7 @@ void main() { oColor = uColor; } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // dst = stored alpha; src factor GL_DST_ALPHA, dst factor GL_ZERO, source white - // => the destination colour becomes (storedAlpha, storedAlpha, storedAlpha). + // => the destination color becomes (storedAlpha, storedAlpha, storedAlpha). glEnable(GL_BLEND); glBlendFunc(GL_DST_ALPHA, GL_ZERO); glUniform4f(colorLocation, 1.0f, 1.0f, 1.0f, 1.0f); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/TriangleScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/TriangleScenario.cpp index 367e0b69..65b0fd89 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/TriangleScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/TriangleScenario.cpp @@ -33,11 +33,11 @@ // MG_Impl - it is reached only through eglSwapBuffers -> BackendObject::SwapEGLBuffers - so a // scenario that never swaps never touches it, and B would then exercise a STRICT SUBSET of // what ClearThenReadPixelsScenario already covers. BRIEF-P5 4.B lists Present(67) among the -// catalogue rows this target needs, so the frame boundary is here on purpose: B is A's slot +// catalog rows this target needs, so the frame boundary is here on purpose: B is A's slot // set plus DrawArrays, not minus Present. // // 4. THE SECOND CASE REDRAWS ACROSS A FRAME BOUNDARY WITHOUT REBUILDING ANYTHING. The VBO, the -// program and the VAO outlive the swap and only the clear colour changes. Under split that +// program and the VAO outlive the swap and only the clear color changes. Under split that // is the difference between "the client re-declares every object every frame" (which would // pass a single-frame test and be the whole cost of the design) and a steady state; under // monolith it is the backend's per-frame retire/aging path, which is exactly where P3a's @@ -91,7 +91,7 @@ void main() { oColor = vec4(vColor, 1.0); } // A single triangle with its base at y = -0.8 and its apex at y = +0.8, so the // interior box the cases assert on (the middle 10% of the width, a fifth of the way up) // is far from every edge and the corner box they assert the CLEAR on is far outside it. - // Flat green: one colour over the whole primitive means an offender pixel is a real + // Flat green: one color over the whole primitive means an offender pixel is a real // disagreement rather than an interpolation rounding difference between two drivers. constexpr Vertex kTriangle[3] = { {-0.8f, -0.8f, 0.0f, 1.0f, 0.0f}, @@ -215,7 +215,7 @@ void main() { oColor = vec4(vColor, 1.0); } Gl().EndFrame(); } - // Steady state: the same VBO, program and VAO across a swap, with only the clear colour + // Steady state: the same VBO, program and VAO across a swap, with only the clear color // changing. Nothing is re-created, so a client that re-declared its objects every frame and // a backend that lost them at the frame boundary both show up here and in no single-frame // case. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/UnboundImageDescriptorScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/UnboundImageDescriptorScenario.cpp index 41774ec2..3f7790c6 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/UnboundImageDescriptorScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/UnboundImageDescriptorScenario.cpp @@ -27,7 +27,7 @@ // dispatch filled. All of it is unrelated to the unbound resource and all of it disappeared. // // The unbound resource is STATICALLY USED in every case, because an unreferenced one is -// optimised out before it ever reaches a descriptor and would prove nothing. Where the use is a +// optimized out before it ever reaches a descriptor and would prove nothing. Where the use is a // read it sits behind a uniform-controlled branch that is false at runtime - the descriptor is // declared and must be written, but no undefined value reaches an assertion. Where it is a write // (the `writeonly` cases, which is how the real workloads spell it) it is unconditional: GL says @@ -348,7 +348,7 @@ void main() { const Image image = ReadPixels(kFboSize, kFboSize); ASSERT_FALSE(image.Empty()) << "the readback came back empty"; - // Whole-region, not a centre pixel: the quad covers the target exactly, so + // Whole-region, not a center pixel: the quad covers the target exactly, so // anything short of all of it is a failure worth naming. EXPECT_TRUE(RegionIsMostly(image, 0, kFboSize - 1, 0, kFboSize - 1, "green", 0.0, std::string("the quad drawn with an unbound ") + what)) diff --git a/MobileGL/MG_IntegrationTest/Scenarios/UnboundUniformBlockScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/UnboundUniformBlockScenario.cpp index 80b7208e..57253f4e 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/UnboundUniformBlockScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/UnboundUniformBlockScenario.cpp @@ -18,7 +18,7 @@ // dereferenced it with nothing there: a SIGSEGV inside the draw or the dispatch, taking the whole // process with it. It now answers with a zeroed block of the reflected size. // -// The block is STATICALLY USED in every case, because an unreferenced block is optimised out +// The block is STATICALLY USED in every case, because an unreferenced block is optimized out // before it ever reaches a descriptor and would prove nothing. Its one read sits behind a // uniform-controlled branch that is false whenever the point is empty, so no undefined value // reaches an assertion. Each case also binds a buffer at the same point and reads it back through @@ -166,15 +166,15 @@ void main() { } // The block must be ACTIVE and at kUniformPoint, and the guard uniform must exist: - // if either were optimised away the program would never ask for the empty point and + // if either were optimized away the program would never ask for the empty point and // every case below would pass without testing anything. static void ExpectTheBlockIsLiveAtThePoint(GLuint program) { const GLuint block = glGetUniformBlockIndex(program, "Target"); - ASSERT_NE(block, GL_INVALID_INDEX) << "the uniform block was optimised out - the case proves nothing"; + ASSERT_NE(block, GL_INVALID_INDEX) << "the uniform block was optimized out - the case proves nothing"; GLint binding = -1; glGetActiveUniformBlockiv(program, block, GL_UNIFORM_BLOCK_BINDING, &binding); ASSERT_EQ(binding, static_cast(kUniformPoint)) << "the block is not at the point under test"; - ASSERT_NE(glGetUniformLocation(program, "u_read"), -1) << "the guard uniform was optimised out"; + ASSERT_NE(glGetUniformLocation(program, "u_read"), -1) << "the guard uniform was optimized out"; ASSERT_EQ(FirstGLError(), 0u) << "querying the block raised a GL error"; } diff --git a/MobileGL/MG_IntegrationTest/Scenarios/UniformInitializerScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/UniformInitializerScenario.cpp index d21adfc9..57658f12 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/UniformInitializerScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/UniformInitializerScenario.cpp @@ -11,7 +11,7 @@ // Desktop GLSL has allowed "uniform int i = 1;" since 1.20, and the initializer is not a // suggestion: it is the value the uniform reads until the application calls glUniform*, and // the value it goes back to after every relink. Nothing in the API reports it, so a driver -// that drops it is indistinguishable from one that honours it until a shader that never sets +// that drops it is indistinguishable from one that honors it until a shader that never sets // the uniform produces the wrong pixels. // // MobileGL parses with Vulkan-relaxed rules, which sweep default-block uniforms into one diff --git a/MobileGL/MG_IntegrationTest/Scenarios/UnlocatedIoBlockScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/UnlocatedIoBlockScenario.cpp index 97596c71..19eb2c27 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/UnlocatedIoBlockScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/UnlocatedIoBlockScenario.cpp @@ -32,9 +32,9 @@ // registrations with the emulation off, so both spellings of the interface are covered and a // regression in either shows up. // -// Colour code, so a failure names its own cause: +// Color code, so a failure names its own cause: // green - the payload crossed all four stage boundaries, which is the pass. -// blue - the clear colour: nothing was drawn at all (the program did not link, or the +// blue - the clear color: nothing was drawn at all (the program did not link, or the // backend program was rejected and every draw became a no-op). // red - the pipeline ran but the plain (non-block) varying did not arrive, i.e. the // failure is not about interface blocks. @@ -271,7 +271,7 @@ void main() // Same calibration IoBlockNameCollisionScenario uses, and for the same reason: // GL_MAX_TESS_GEN_LEVEL is a real backend answer while GL_MAX_GEOMETRY_* are - // frontend constants, so a stack with no five-stage pipeline is recognised by + // frontend constants, so a stack with no five-stage pipeline is recognized by // trying to build one, not by asking. static bool BackendHostsTessellationAndGeometry() { GLint maxTessGenLevel = 0; @@ -328,7 +328,7 @@ void main() return program; } - // Clears to BLUE, so "the draw painted nothing" is a colour of its own rather + // Clears to BLUE, so "the draw painted nothing" is a color of its own rather // than something that could be mistaken for a zeroed payload. Rgba8 DrawAndReadCentre(GLuint program) const { glViewport(0, 0, Gl().Width(), Gl().Height()); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/UploadOrderScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/UploadOrderScenario.cpp index c85d2aed..d9a5783b 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/UploadOrderScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/UploadOrderScenario.cpp @@ -15,7 +15,7 @@ // references the texture BEFORE the upload in the same recording and checks the command saw the // old texels (or that the upload is not overwritten by it): // - a draw sampling the texture (the sampled-texture path); -// - a clear of the texture as a colour attachment, issued as the FIRST command after a +// - a clear of the texture as a color attachment, issued as the FIRST command after a // glFinish, so it is resolved before the recording that holds it has begun. // Every case reads back only after all of its commands, so no readback orders them for us. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/VaoShadowScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/VaoShadowScenario.cpp index 2da81c9c..8f88e8a1 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/VaoShadowScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/VaoShadowScenario.cpp @@ -37,7 +37,7 @@ namespace MGITest { namespace { - // Position in [0, 1] (+ an x offset per instance), colour from attribute 1. + // Position in [0, 1] (+ an x offset per instance), color from attribute 1. constexpr const char* kVS = R"(#version 330 core layout(location = 0) in vec2 aPos; layout(location = 1) in vec4 aColor; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/VertexAttribBindingScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/VertexAttribBindingScenario.cpp index bfa2efd0..dfef9b89 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/VertexAttribBindingScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/VertexAttribBindingScenario.cpp @@ -344,7 +344,7 @@ void main() { } // glVertexBindingDivisor is per BINDING POINT: it has to reach every attribute - // pointed at that binding, and the instance step must honour the divisor rather + // pointed at that binding, and the instance step must honor the divisor rather // than advancing once per instance. TEST_F(VertexAttribBindingScenario, BindingDivisorAppliesToEveryAttributeOnThePoint) { if (!Ready()) GTEST_SKIP(); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/ViewportArrayScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/ViewportArrayScenario.cpp index 37338ab4..563ffe69 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/ViewportArrayScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/ViewportArrayScenario.cpp @@ -20,7 +20,7 @@ // (i/16, 1 - i/16), a quad at each end of clip space, and gl_FragCoord.z read back. // This is the claim that fails loudest against a single-viewport backend, because the // geometry is still in the right place while every depth comes back as viewport 0's. -// 3. The per-index SCISSOR TEST ENABLE is honoured. Vulkan has no per-viewport scissor-test +// 3. The per-index SCISSOR TEST ENABLE is honored. Vulkan has no per-viewport scissor-test // toggle, so a disabled index has to be given the whole framebuffer as its rectangle; the // case draws the same primitive into the same index twice, once with the test off and once // with it on, and requires the two results to differ in the documented direction. @@ -255,7 +255,7 @@ void main() { fragColor = gl_FragCoord.z; } return 0; } - // An R32I colour target, pre-filled with kUnwritten so "nothing was drawn here" is + // An R32I color target, pre-filled with kUnwritten so "nothing was drawn here" is // distinguishable from "index 0 was drawn here". struct IntTarget { GLuint fbo = 0; @@ -298,8 +298,8 @@ void main() { fragColor = gl_FragCoord.z; } return pixels; } - // The centre of grid cell (x, y), in the bottom-left-origin coordinates glReadPixels - // returns. Sampling the centre rather than a corner keeps the assertion about WHICH + // The center of grid cell (x, y), in the bottom-left-origin coordinates glReadPixels + // returns. Sampling the center rather than a corner keeps the assertion about WHICH // viewport was selected rather than about edge rounding. static GLint CellCentre(const std::vector& pixels, int stride, int x, int y) { const int px = x * kCellSize + kCellSize / 2; @@ -349,7 +349,7 @@ void main() { fragColor = gl_FragCoord.z; } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - // The default framebuffer is 8-bit RGBA, so the index travels as a colour: cell i is + // The default framebuffer is 8-bit RGBA, so the index travels as a color: cell i is // painted with red = i * 16, which is exact in 8 bits for i in [0, 16). const char* const kColorFragmentSource = R"(#version 410 core flat in int gsIndex; @@ -357,7 +357,7 @@ layout(location = 0) out vec4 fragColor; void main() { fragColor = vec4(float(gsIndex) * 16.0 / 255.0, 0.0, 0.0, 1.0); } )"; const GLuint colorProgram = BuildProgram(kGridGeometrySource, kColorFragmentSource); - ASSERT_NE(colorProgram, 0u) << "colour program failed to build: " << m_buildLog; + ASSERT_NE(colorProgram, 0u) << "color program failed to build: " << m_buildLog; SetupGridViewports(cellW, cellH); glUseProgram(colorProgram); @@ -374,7 +374,7 @@ void main() { fragColor = vec4(float(gsIndex) * 16.0 / 255.0, 0.0, 0.0, 1.0); } const int red = pixels[(static_cast(py) * surfaceW + px) * 4]; const int expected = (y * kGridSide + x) * 16; // One LSB of slack for an 8-bit round trip; the values are 16 apart, so this - // cannot confuse two neighbouring indices. + // cannot confuse two neighboring indices. EXPECT_LE(std::abs(red - expected), 1) << "default-framebuffer cell (" << x << ", " << y << ") holds red=" << red << ", expected " << expected << ". A vertically mirrored grid means the Y-flip was applied to viewport 0 " @@ -432,7 +432,7 @@ void main() { fragColor = vec4(float(gsIndex) * 16.0 / 255.0, 0.0, 0.0, 1.0); } const float farDepth = 1.0f - static_cast(i) / 16.0f; // The tolerance covers depth-buffer-free rasterization of gl_FragCoord.z on a // software rasterizer; the per-index values are 1/16 apart, so it cannot let a - // neighbouring viewport's range through, and viewport 0's range (0, 1) differs + // neighboring viewport's range through, and viewport 0's range (0, 1) differs // from every other index by at least 1/16. EXPECT_NEAR(pixels[i], nearDepth, 1.0e-3f) << "viewport " << i << " near-plane depth; got viewport 0's range if this is 0"; @@ -528,7 +528,7 @@ void main() { fragColor = vec4(float(gsIndex) * 16.0 / 255.0, 0.0, 0.0, 1.0); } // (the NoViewportArrayEmulation. ctest entry) and requires case 1's // result to COLLAPSE: with no routing, every geometry invocation rasterizes against // viewport 0's rectangle, so the last invocation paints the whole surface and every cell - // reads 15 instead of its own index. That is the pre-emulation behaviour this backend had + // reads 15 instead of its own index. That is the pre-emulation behavior this backend had // (and the failure signature KHR-GL43.viewport_array reported on it), pinned here so that // (a) the three cases above are known to be testing the emulation and not the weather, // and (b) the switch itself has a test. @@ -644,7 +644,7 @@ void main() { fragColor = 7; } glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0); ASSERT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GL_FRAMEBUFFER_COMPLETE) - << "R32I is required to be colour-renderable; an incomplete target would make every " + << "R32I is required to be color-renderable; an incomplete target would make every " "assertion below vacuous"; glViewport(0, 0, kSurfaceSide, kSurfaceSide); diff --git a/MobileGL/MG_IntegrationTest/Scenarios/WindowPassGateScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/WindowPassGateScenario.cpp index e2d26322..64648dfe 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/WindowPassGateScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/WindowPassGateScenario.cpp @@ -25,7 +25,7 @@ // shape), frames that never touch the window at all, and a readback of the window inside the // frame. Every frame changes what it draws, so a window pass that ran ahead of the off-screen // work it reads, or a frame that lost its off-screen half, shows up as the previous frame's -// colours. The DirectVulkan.WindowPassGate. entry also asserts the renderer's latched MGLOG_I: +// colors. The DirectVulkan.WindowPassGate. entry also asserts the renderer's latched MGLOG_I: // on a renderer that submits the frame in one piece it is the assertion that goes red. #include @@ -83,7 +83,7 @@ void main() { o_color = texture(uTex, vUv); } const char* name; }; - // Saturated colours only: ColorName() names them exactly whatever the rounding. + // Saturated colors only: ColorName() names them exactly whatever the rounding. constexpr NamedColor kCycle[] = { {1.0f, 0.0f, 0.0f, "red"}, {0.0f, 1.0f, 0.0f, "green"}, {0.0f, 0.0f, 1.0f, "blue"}, {1.0f, 1.0f, 0.0f, "yellow"}, {1.0f, 1.0f, 1.0f, "white"}, @@ -98,7 +98,7 @@ void main() { o_color = texture(uTex, vUv); } return kCycle[(frame + 2) % kCycleLength]; } - // The NDC rectangle [x0, x1] x [y0, y1] in one colour; aPos at 0, aColor at 1. + // The NDC rectangle [x0, x1] x [y0, y1] in one color; aPos at 0, aColor at 1. void DrawRect(unsigned int program, float x0, float y0, float x1, float y1, const NamedColor& c) { const float vertices[] = { x0, y0, c.r, c.g, c.b, 1.0f, x1, y0, c.r, c.g, c.b, 1.0f, diff --git a/MobileGL/MG_IntegrationTest/Scenarios/WireMipShapeScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/WireMipShapeScenario.cpp index 8bd8e2dd..1b9dd9a9 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/WireMipShapeScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/WireMipShapeScenario.cpp @@ -14,7 +14,7 @@ // ignores layerCount, so the PIXELS below are right with or without the fix on this host; what // goes red on the host is the validation layer, which the `.Mip3DValidation.` entry runs this // case under (inproc, so the server's Vulkan instance is this process and its stdout is ours). -// The pixel half runs on both backends and every arm, and is what a driver that honours +// The pixel half runs on both backends and every arm, and is what a driver that honors // layerCount would fail. // * A 1D DEPTH chain with no native blit. The depth shader arm renders 2D views, which a 1D image // does not admit; the wire arm handed it the chain anyway. It is now the named decline @@ -76,7 +76,7 @@ namespace MGITest { }; // A 3D RGBA8 chain, 8x8x8 with its full storage, whose level-0 slices come in PAIRS of one - // colour: level 1's slice k is then pair k's colour exactly, and every level below is the + // color: level 1's slice k is then pair k's color exactly, and every level below is the // average of two slices of the level above. A blit that loses the z axis (one slice only, // or slices read as array layers of a 2D image) cannot produce those numbers. TEST_F(WireMipShapeScenario, VolumeChainIsGeneratedAlongItsDepth) { diff --git a/MobileGL/MG_IntegrationTest/Scenarios/WriteRenameScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/WriteRenameScenario.cpp index c950f90c..9421171a 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/WriteRenameScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/WriteRenameScenario.cpp @@ -38,7 +38,7 @@ namespace MGITest { namespace { - // Position in [0, 1] and a per-vertex colour. + // Position in [0, 1] and a per-vertex color. constexpr const char* kVS = R"(#version 330 core layout(location = 0) in vec2 aPos; layout(location = 1) in vec4 aColor; @@ -87,7 +87,7 @@ void main() { o0 = vColor * uTint; } GLuint program = 0, fbo = 0, color = 0, vao = 0, vbo = 0, ibo = 0, ubo = 0; }; - // A target, the program, a VAO over `vertices` (float2 position + ubyte4 colour), a + // A target, the program, a VAO over `vertices` (float2 position + ubyte4 color), a // four-index strip index buffer and a white tint. Scene MakeScene(const std::vector& vertices, std::string* error) { Scene s; diff --git a/MobileGL/MG_IntegrationTest/Scenarios/XfbAfterClipDistanceScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/XfbAfterClipDistanceScenario.cpp index 09d5bca4..ac0094e5 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/XfbAfterClipDistanceScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/XfbAfterClipDistanceScenario.cpp @@ -36,7 +36,7 @@ // * the workload is glcClipDistance.cpp FunctionalTest's inner loop (a program // per (redeclaration, clip count), glEnable(GL_CLIP_DISTANCEi), an FBO per // primitive type, a draw and a readback), including its early-return -// behaviour: on failure the test returns WITHOUT running its "clip clean" +// behavior: on failure the test returns WITHOUT running its "clip clean" // loop, so GL_CLIP_DISTANCE0..N-1 stay enabled for the rest of the process. // That leftover enable state is NOT the carrier (one of the cases below pins // that); the object churn is. @@ -681,7 +681,7 @@ void main (void) // is a hole rather than a courtesy: the defect it pins is DirectVulkan's // alone, and DirectVulkan now comes up headless on any machine at all - a // surfaceless EGL platform over a software ICD (lavapipe) is enough. So - // "DirectVulkan did not initialise" here means the run is MISCONFIGURED, + // "DirectVulkan did not initialize" here means the run is MISCONFIGURED, // not that the machine has no GPU, and it must not report green. // // Local on purpose: the harness-wide skip semantics are deliberate @@ -723,7 +723,7 @@ void main (void) // partial one asked the staged-coverage assertion for a range wider than anything staged // and died on Fatal{StageSnapshotTooNarrow, "xfb_scatter_pre_capture"}. // - // The monolith arm has always been right here: `staged` is a value-initialised + // The monolith arm has always been right here: `staged` is a value-initialized // Vector, so an unreadable source means the scatter runs over zeroes and uploads // them - which is byte for byte what it gets from a fresh MappedData(). Skipping the COPY // is the whole of the difference between the two arms; skipping the TARGET was the bug. diff --git a/MobileGL/MG_IntegrationTest/Scenarios/XfbCaptureBufferReuseScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/XfbCaptureBufferReuseScenario.cpp index 1ba7d443..0eefcf9b 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/XfbCaptureBufferReuseScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/XfbCaptureBufferReuseScenario.cpp @@ -159,7 +159,7 @@ void main() { const float expected = value + static_cast(i); const float got = data[i]; // isfinite first: every ordered comparison against a NaN is false, so a - // pair of one-sided range tests REPORTS SUCCESS for uninitialised + // pair of one-sided range tests REPORTS SUCCESS for uninitialized // storage that happens to read as NaN - which is exactly the failure // these scenarios exist to catch. if (!std::isfinite(got) || std::fabs(got - expected) > 0.01f) { diff --git a/MobileGL/MG_IntegrationTest/Scenarios/XfbPrimitiveQueryScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/XfbPrimitiveQueryScenario.cpp index a0251188..24282740 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/XfbPrimitiveQueryScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/XfbPrimitiveQueryScenario.cpp @@ -189,7 +189,7 @@ void main() { const float expected = static_cast(point) + static_cast(component); const float got = record[component]; // isfinite first: every ordered comparison against a NaN is false, so a - // pair of one-sided range tests REPORTS SUCCESS for uninitialised storage + // pair of one-sided range tests REPORTS SUCCESS for uninitialized storage // that happens to read as NaN. if (!std::isfinite(got) || std::fabs(got - expected) > 0.01f) { return ::testing::AssertionFailure() diff --git a/MobileGL/MG_IntegrationTest/Scenarios/XfbRepeatedCaptureScenario.cpp b/MobileGL/MG_IntegrationTest/Scenarios/XfbRepeatedCaptureScenario.cpp index e94c321d..f39a6e27 100644 --- a/MobileGL/MG_IntegrationTest/Scenarios/XfbRepeatedCaptureScenario.cpp +++ b/MobileGL/MG_IntegrationTest/Scenarios/XfbRepeatedCaptureScenario.cpp @@ -11,7 +11,7 @@ // // The conformance suite exposed a whole family of transform feedback failures that no // existing scenario could reproduce, because every one of them ran ONE capture, from a -// VERTEX stage, in a freshly initialised process. What the suite actually does is +// VERTEX stage, in a freshly initialized process. What the suite actually does is // different in three ways at once, and each of them turned out to matter: // // * it runs case after case in ONE GL context, resetting state between them - and the diff --git a/MobileGL/MG_Pipe/DirtySurface.def b/MobileGL/MG_Pipe/DirtySurface.def index bf7a8197..71636766 100644 --- a/MobileGL/MG_Pipe/DirtySurface.def +++ b/MobileGL/MG_Pipe/DirtySurface.def @@ -169,7 +169,7 @@ X(UseProgram, NEW_SHADER|NEW_SAMPLER_VIEWS|NEW_SHADER_IMAGES) \ X(BindVertexArray, NEW_VERTEX_ELEMENTS) \ /* NOT NEW_SHADER, and the derivation refutes it outright rather than leaving it a */ \ - /* judgement: this mutator writes m_boundProgramPipeline (plus the pipeline name table) */ \ + /* judgment: this mutator writes m_boundProgramPipeline (plus the pipeline name table) */ \ /* and bit 6's shutter reads m_currentProgram's lifetime id and link version - disjoint */ \ /* sets, on every path. That is not an oversight in the shutter either: it reads */ \ /* GetCurrentProgram() and DELIBERATELY NOT GetProgramForDraw(), because the tracker */ \ diff --git a/MobileGL/MG_Pipe/FatalFamilies.def b/MobileGL/MG_Pipe/FatalFamilies.def index 6996f46c..6dfc31b8 100644 --- a/MobileGL/MG_Pipe/FatalFamilies.def +++ b/MobileGL/MG_Pipe/FatalFamilies.def @@ -48,7 +48,7 @@ X(UnsizedReadback, ProtocolCorruption, "a readback arrived with no declared size") \ X(BlobMissing, ProtocolCorruption, "a record named a blob that was never staged") \ X(BlobNotStaged, ProtocolCorruption, "a blob was referenced before its staging completed") \ - X(ArtefactsMissing, ProtocolCorruption, "a program create arrived with no artefacts") \ + X(ArtefactsMissing, ProtocolCorruption, "a program create arrived with no artifacts") \ X(ArchiveEmpty, ProtocolCorruption, "a create_*_state archive carried no payload") \ X(BarrierViolation, ProtocolCorruption, "a field was pulled across a verb boundary the barrier forbids") \ X(UnimplementedAdoptTier, ProtocolCorruption, "MOBILEGL_IPC_ADOPT_TIER named a tier P5 does not implement") \ diff --git a/MobileGL/MG_Pipe/MGPipe.h b/MobileGL/MG_Pipe/MGPipe.h index 8207c8a3..eda274c4 100644 --- a/MobileGL/MG_Pipe/MGPipe.h +++ b/MobileGL/MG_Pipe/MGPipe.h @@ -78,7 +78,7 @@ namespace MobileGL::MG_Pipe { // ---- MOBILEGL_PIPE_PUSH's runtime bitmask (Config.h Features.PipePush) ---- // // One bit per SUBSYSTEM, so an A/B is per subsystem rather than all-or-nothing, and - // bit 63 for the one BEHAVIOUR the design has to be measured against. Bits are + // bit 63 for the one BEHAVIOR the design has to be measured against. Bits are // allocated in ROADMAP order and never reused: an operator's recorded 0x7f has to keep // meaning what it meant. // @@ -120,7 +120,7 @@ namespace MobileGL::MG_Pipe { // which is how "THREE OF THEM" above stayed wrong through two phases. inline constexpr Uint64 kMGPipeSubsystemBufferBindings = 1ull << 13; // bits 14..62 reserved for the later phases, allocated in ROADMAP order. - // NOT a subsystem, a BEHAVIOUR: turn OFF client-side content addressing of CSOs, so + // NOT a subsystem, a BEHAVIOR: turn OFF client-side content addressing of CSOs, so // every pipeline-version change mints a fresh CSO and the map is never probed. This is // the negative control the whole CSO design is measured against (ROADMAP.md P2). inline constexpr Uint64 kMGPipeBehaviourNoCsoContentAddressing = 1ull << 63; @@ -197,7 +197,7 @@ namespace MobileGL::MG_Pipe { return ""; } - // Rows 1 and 6 became live behaviour when D3 made every reader read the table (before that + // Rows 1 and 6 became live behavior when D3 made every reader read the table (before that // the bit-7 tests were hard-coded in Managers.cpp and DirectGLES.cpp and these rows were // dead data). An edit that drops either row now makes BOTH readers agree, so nothing // downstream can catch it; these two lines can. @@ -215,7 +215,7 @@ namespace MobileGL::MG_Pipe { static_assert(MGPipeSubsystemDependenciesAreSet(kMGPipeSubsystemTextureResources, 0x1fffull), "0x1fff is P4a's own arm and every row of it must be satisfied"); - // The catalogue itself. Only macros, so it is safe to expand inside the namespace, and + // The catalog itself. Only macros, so it is safe to expand inside the namespace, and // consumers (the unit test, later the transport) get MGP_CALL_LIST from this header. #include "PipeCalls.def" diff --git a/MobileGL/MG_Pipe/MGPipeHandles.h b/MobileGL/MG_Pipe/MGPipeHandles.h index e985906d..c7e41195 100644 --- a/MobileGL/MG_Pipe/MGPipeHandles.h +++ b/MobileGL/MG_Pipe/MGPipeHandles.h @@ -12,8 +12,8 @@ // MGPipe object identity (plan B section 4.2). // // A handle is a {slot, gen} pair minted by the CLIENT and never by the server: no create_* -// call in the catalogue returns a server-cast handle, which is the deliberate deviation -// from driver-minted handles (D1) that lets the whole catalogue be remoted with ZERO creation round +// call in the catalog returns a server-cast handle, which is the deliberate deviation +// from driver-minted handles (D1) that lets the whole catalog be remoted with ZERO creation round // trips. // // Slots are dense and allocated PER KIND, so the server's object table is an array rather diff --git a/MobileGL/MG_Pipe/MGPipeRenderStateSpans.cpp b/MobileGL/MG_Pipe/MGPipeRenderStateSpans.cpp index 9b1f9da7..38bde69b 100644 --- a/MobileGL/MG_Pipe/MGPipeRenderStateSpans.cpp +++ b/MobileGL/MG_Pipe/MGPipeRenderStateSpans.cpp @@ -10,7 +10,7 @@ // generated/PipeSpanTable.inc declares (ARCHITECTURE.md §5.3). The pipeline half holds every // byte a BumpVersions() setter writes, which covers all fixed-function state Magma's pipeline // build reads and more; the extra bytes cost nothing because the subset is hashed only when -// m_pipelineStateVersion moves. Render-pass facts (colour attachment count, rasterization +// m_pipelineStateVersion moves. Render-pass facts (color attachment count, rasterization // samples and the effective sample mask derived from them) are not in RenderStateParameters, // so Magma keeps renderPassHash beside the CSO handle in its pipeline memo key. #include diff --git a/MobileGL/MG_Pipe/MGPipeTypes.h b/MobileGL/MG_Pipe/MGPipeTypes.h index 24723017..a8935739 100644 --- a/MobileGL/MG_Pipe/MGPipeTypes.h +++ b/MobileGL/MG_Pipe/MGPipeTypes.h @@ -62,7 +62,7 @@ namespace MobileGL::MG_Pipe { }; MGP_ASSERT_POD(MGPBox, 24); - // Where an asynchronous answer lands. Every server query in this catalogue is + // Where an asynchronous answer lands. Every server query in this catalog is // async-with-handle; none of them blocks (section 4.4.6, "the total rule"). struct MGPReplySlot { Uint64 Id; @@ -281,7 +281,7 @@ namespace MobileGL::MG_Pipe { static_assert(MGPipeEveryTextureTargetIsMapped(), "a TextureTarget enumerator has no MGPResourceDesc::Target row: add it to " "MGPipeResourceTargetForTextureTarget, and give it an enumerator of its own " - "rather than folding it onto a neighbour (D-A3)"); + "rather than folding it onto a neighbor (D-A3)"); static_assert(MGPipeResourceTargetForTextureTarget(MobileGL::TextureTarget::Texture2D) != MGPipeResourceTargetForTextureTarget(MobileGL::TextureTarget::TextureRectangle), "a rectangle texture is not a 2D texture on the wire; both backends switch on " @@ -503,7 +503,7 @@ namespace MobileGL::MG_Pipe { MGP_ASSERT_POD(MGPBindRenderState, 12); // The half of the render state that must NOT mint a CSO: viewport, scissor, depth - // range, blend colour, line width, polygon offset, stencil ref/write mask, clear + // range, blend color, line width, polygon offset, stencil ref/write mask, clear // values, hints, the point-size family and the primitive-restart index. This is what // keeps glViewport from evicting Magma's pipeline memo (D-B1). // @@ -574,7 +574,7 @@ namespace MobileGL::MG_Pipe { // (TextureState/TextureObject.h's m_sampler, constructed by TextureObjectBase's // constructor). GL 4.6 core table 23.18 makes filter/wrap/compare/border SAMPLER state, // and Espryt pushes it with glTexParameter* onto the TEXTURE rather than with - // glBindSampler onto the unit - behaviour P4a preserves exactly. Naming the CSO rather + // glBindSampler onto the unit - behavior P4a preserves exactly. Naming the CSO rather // than widening this payload with a filter/wrap/border block is what keeps ONE authority // for one value: SyncTextureParamsToBackend reads this record, SyncBuiltinSamplerToBackend // reads that CSO's SamplerParameters, and the two pushes stay two pushes. @@ -630,7 +630,7 @@ namespace MobileGL::MG_Pipe { // GetLinkVersion, and a FAILED relink of a bound program moves it too. The server's // clean condition needs the difference spelled, because a draw on a program the // frontend reports unlinked DECLINES (the frontend raises INVALID_OPERATION) and a - // record that cannot say so leaves the twin rebuilding from empty artefacts. + // record that cannot say so leaves the twin rebuilding from empty artifacts. // // THE DESCRIPTOR GREW 192 -> 200 AND THE DRAFT'S "in the descriptor's existing pad" // WAS WRONG: the four bytes above end at offset 24 and MGPBlobRef is 8-aligned, so @@ -651,7 +651,7 @@ namespace MobileGL::MG_Pipe { // MGPSurface::Kind's three values (P4a, ID-12 / esprytobj DV-4). MGPipeKind is REUSED // rather than a second three-value enum minted beside it: it already spells Texture and - // Renderbuffer, its None is 0, and a zero-initialised MGPSurface is therefore ALREADY the + // Renderbuffer, its None is 0, and a zero-initialized MGPSurface is therefore ALREADY the // empty attachment point this record describes - {Res = kMGPipeNullHandle, Kind = None} // and every other field zero. The static_assert is what keeps that true if MGPipeKind is // ever reordered. @@ -659,7 +659,7 @@ namespace MobileGL::MG_Pipe { inline constexpr Uint8 kMGPipeSurfaceKindTexture = static_cast(MGPipeKind::Texture); inline constexpr Uint8 kMGPipeSurfaceKindRenderbuffer = static_cast(MGPipeKind::Renderbuffer); static_assert(kMGPipeSurfaceKindNone == 0, - "a zero-initialised MGPSurface must already be the empty attachment point"); + "a zero-initialized MGPSurface must already be the empty attachment point"); // MGPSurface::TextureTarget for a point that names no texture: the renderbuffer point and // the empty point both carry it. It is MobileGL::TextureTarget::Unknown, which is -1 and @@ -913,7 +913,7 @@ namespace MobileGL::MG_Pipe { // // XFB IS NOT ONE OF THEM: set_stream_output_targets carries a Generation this payload has // no field for and its capture points are span-scoped state latched at Begin, so the - // catalogue's split between the two rows stays (§5.7). + // catalog's split between the two rows stays (§5.7). inline constexpr Uint32 kMGPipeShaderBufferClassUniform = 0; inline constexpr Uint32 kMGPipeShaderBufferClassShaderStorage = 1; inline constexpr Uint32 kMGPipeShaderBufferClassAtomicCounter = 2; @@ -1046,7 +1046,7 @@ namespace MobileGL::MG_Pipe { // record now carries all three views VERBATIM, as the frontend computed them, and the // applier writes each view from its own array; ValueClass stays as the record of which // view the application wrote directly (the verify comparator covers it, and the - // emission-side suppressor compares the three views, not it). This is the catalogue's + // emission-side suppressor compares the three views, not it). This is the catalog's // second payload-size amendment after P5b's MGPCopyRegion 64 -> 72 (CONTRACT-P5C.md §7.6): // 24 -> 56 bytes, and PipeCatalogueTest pins the new size. struct MGPAttribValue { @@ -1090,10 +1090,10 @@ namespace MobileGL::MG_Pipe { // libraries: the applier that installs it, and (in a verify build) the compare-at-read hook in // MG_Impl/Pipe/PipeFill.cpp, whose oracle for the pack half inside that window IS this value. // Two hand-typed copies would drift silently in the ONE direction that matters - the hook - // would stop recognising the window and start reporting a divergence that is not one - so + // would stop recognizing the window and start reporting a divergence that is not one - so // MG_Pipe, which owns MGPPixelPackState, owns the constant as well. // - // Value-initialised and then the five fields the applier sets: RowLength / SkipRows / + // Value-initialized and then the five fields the applier sets: RowLength / SkipRows / // SkipPixels / SkipImages are already 0 by PixelStoreParameters' own defaults and are spelled // out anyway, because "neutral" is a statement about every member rather than about the ones // whose default happens to be right. @@ -1237,7 +1237,7 @@ namespace MobileGL::MG_Pipe { } // The per-record half of resource_respecify's kNeedsAck: the call flag says a record may - // need an acknowledgement, and this decides. Only an immutable buffer (glBufferStorage) is a + // need an acknowledgment, and this decides. Only an immutable buffer (glBufferStorage) is a // synchronous allocation; glBufferData is not. glTexStorage* also sets Immutable, but texture // and renderbuffer storage is allocated lazily at sync time, so neither may ack // (ARCHITECTURE.md §8.3). PipeCatalogue.ResourceRespecifyAcksOnlyImmutableStorage @@ -1459,7 +1459,7 @@ namespace MobileGL::MG_Pipe { // GL_PARAMETER_BUFFER, ParameterOffset = drawcount (a byte // offset); the backend reads the real count from that buffer // Buffer / Offset / Stride the bound GL_DRAW_INDIRECT_BUFFER, the `indirect` byte offset - // and the stride (0 = tightly packed; the backend normalises). + // and the stride (0 = tightly packed; the backend normalizes). struct MGPDrawIndirect { MGPipeHandle Buffer; MGPipeHandle ParameterBuffer; @@ -1683,7 +1683,7 @@ namespace MobileGL::MG_Pipe { }; MGP_ASSERT_POD(MGPBindContext, 8); - // shared_image: colour buffers the server allocates and exports as dma-buf descriptors, so + // shared_image: color buffers the server allocates and exports as dma-buf descriptors, so // one client's frames reach another client's textures without leaving GPU memory. Every op // answers through the reply slot with an MGPSharedImageReply; a descriptor (Allocate, // NativeFence) reaches the client on the aux socket before the reply is posted. Damage holds @@ -1704,7 +1704,7 @@ namespace MobileGL::MG_Pipe { inline constexpr Uint32 kMGPBufferAgeDamageRegionFollows = 1u; inline constexpr Uint32 kMGPNativeFenceFdFollows = 1u; - // An Import of a YUV fourcc (NV12, P010) carries its planes and colour hints in Damage, with + // An Import of a YUV fourcc (NV12, P010) carries its planes and color hints in Damage, with // DamageCount = kMGPImportPlaneWords (the field is a Present's otherwise, and 0 on an RGBA // Import): both planes live in the one descriptor the Import sends, at these byte offsets and // row pitches. The hints are EGL_EXT_image_dma_buf_import's values, 0 where not given. diff --git a/MobileGL/MG_Pipe/MGPipeValueTypes.h b/MobileGL/MG_Pipe/MGPipeValueTypes.h index c77bdbb0..f92642b5 100644 --- a/MobileGL/MG_Pipe/MGPipeValueTypes.h +++ b/MobileGL/MG_Pipe/MGPipeValueTypes.h @@ -271,11 +271,11 @@ namespace MobileGL { Float PolygonOffsetUnits = 0.0f; // GL_POLYGON_OFFSET_CLAMP (GL 4.6 core 14.6.5 / GL_EXT_polygon_offset_clamp): the maximum // magnitude of the offset glPolygonOffsetClamp's third argument allows. Zero - the default - // - means "no clamp", which is exactly the behaviour glPolygonOffset leaves behind. + // - means "no clamp", which is exactly the behavior glPolygonOffset leaves behind. Float PolygonOffsetClamp = 0.0f; // glClipControl (GL 4.5 core 13.5). Defaults per table 23.7 are the pre-4.5 fixed - // behaviour: origin at the lower left, depth mapped from -1..1. + // behavior: origin at the lower left, depth mapped from -1..1. GLenum ClipOrigin = GL_LOWER_LEFT; GLenum ClipDepthMode = GL_NEGATIVE_ONE_TO_ONE; @@ -307,7 +307,7 @@ namespace MobileGL { Bool DepthClampEnabled = false; Bool TextureCubeMapSeamlessEnabled = false; - // Clear State. GL's initial clear colour is (0, 0, 0, 0) (GL 4.6 core table 23.24): an + // Clear State. GL's initial clear color is (0, 0, 0, 0) (GL 4.6 core table 23.24): an // application that never calls glClearColor - or caches it and skips the redundant call - // clears to transparent, and offscreen layers depend on it. FloatVec4 ClearColor = FloatVec4(0.0f, 0.0f, 0.0f, 0.0f); @@ -326,7 +326,7 @@ namespace MobileGL { // GL_EXT_fragment_shading_rate: the pipeline rate glShadingRateEXT sets and the two // combiner operations of glShadingRateCombinerOpsEXT. Placed in the three alignment bytes // between SampleCoverageInvert and SampleMaskValue, the way FramebufferSrgbEnabled and its - // two neighbours were, so sizeof and every existing offset stay put. All three are + // two neighbors were, so sizeof and every existing offset stay put. All three are // PIPELINE state (their setters call BumpVersions). The rate is stored in the packed form // the extension defines for gl_ShadingRateEXT and the attachment texels - // (log2(width) << 2) | log2(height), so 1x1 = 0 - and each op as its index in @@ -530,9 +530,9 @@ namespace MobileGL { Unknown = -1 }; - // Which of the three GL_TEXTURE_BORDER_COLOR entry-point families last wrote the border colour, + // Which of the three GL_TEXTURE_BORDER_COLOR entry-point families last wrote the border color, // and therefore which of the three stored representations is AUTHORITATIVE. GL 4.6 core 8.10: - // TexParameterIiv/Iuiv store an integer border colour "unmodified, with an internal data type of + // TexParameterIiv/Iuiv store an integer border color "unmodified, with an internal data type of // integer", TexParameterfv stores a floating-point one, and the derived forms are only a // convenience for a getter of the other spelling. A backend cannot pick the right driver entry // point (glSamplerParameterIiv vs fv) or the right VkBorderColor family without this: numerically @@ -562,7 +562,7 @@ namespace MobileGL { // not on the texture - a texture object reaches it through the sampler object it owns. The // three representations are the float, integer and unsigned-integer forms glSamplerParameterfv, // glSamplerParameterIiv and glSamplerParameterIuiv set; whichever is written last defines - // the colour and the other two follow it, so a getter always has an answer. + // the color and the other two follow it, so a getter always has an answer. FloatVec4 borderColor = {0.0f, 0.0f, 0.0f, 0.0f}; IntVec4 borderColorI = {0, 0, 0, 0}; UintVec4 borderColorUI = {0, 0, 0, 0}; diff --git a/MobileGL/MG_Pipe/PipeApply.cpp b/MobileGL/MG_Pipe/PipeApply.cpp index f50f956e..2babcaac 100644 --- a/MobileGL/MG_Pipe/PipeApply.cpp +++ b/MobileGL/MG_Pipe/PipeApply.cpp @@ -25,7 +25,7 @@ // build only. In monolith the archive does not travel - MGPProgramDesc's seven blob refs are // declared with Size 0 and the two structs ride beside the record through the entry point's // companion pointers - so a push build pays nothing for it and the header keeps its forward -// declarations. The verify build serialises, deserialises and compares before storing, which +// declarations. The verify build serializes, deserialises and compares before storing, which // makes the codec LIVE CODE WITH A GATE rather than dead code with a unit test. #include #endif @@ -897,7 +897,7 @@ namespace MobileGL::MG_Pipe { return &record; } - // Null means "this is not a resource target this catalogue names", which is a corrupt + // Null means "this is not a resource target this catalog names", which is a corrupt // descriptor rather than an unknown object: acting on the wrong table would create, // respecify or destroy an unrelated LIVE object that happens to hold the same slot in // another kind's space, and that is the "act outside its own storage" class. @@ -1574,7 +1574,7 @@ namespace MobileGL::MG_Pipe { #if MOBILEGL_PIPE_VERIFY // THE ARCHIVE'S ROUND TRIP, and it is a VERIFY-ONLY gate on a path that does not - // serialise anything in a shipped build. What it asks is the question a transport will + // serialize anything in a shipped build. What it asks is the question a transport will // ask on the first day it exists and nobody can ask afterwards: does the archive this // client is publishing survive being turned into bytes and back? A field the codec // skips in BOTH directions round-trips perfectly, which is why the unit suite reads the @@ -1589,7 +1589,7 @@ namespace MobileGL::MG_Pipe { Vector reencoded; const char* fault = nullptr; if (encoded.empty()) { - fault = "the encoder produced no bytes for a program that has artefacts"; + fault = "the encoder produced no bytes for a program that has artifacts"; } else if (!MG_State::GLState::DecodeProgramArtifacts(encoded.data(), encoded.size(), decodedLink, decodedSpirv)) { fault = "the archive this client would put on the wire does not decode"; @@ -2366,7 +2366,7 @@ namespace MobileGL::MG_Pipe { // resource_readback and map_persistent resolve through ResolveResource - i.e. against // MGPipeApplier().Resources and never the texture or renderbuffer table - which is right, because // a mapped range, a readback and a persistent donation exist for buffers only. They are - // buffer-only BY CATALOGUE and not by check: MGPFlushRange and MGPReadback carry no kind + // buffer-only BY CATALOG and not by check: MGPFlushRange and MGPReadback carry no kind // at all, and map_persistent's MGPHandleOnly is not asked for one, so there is nothing here // to compare and a mistyped record can only be caught where a discriminator exists. // unmap_persistent is that place, and it Fatals - see there. If a later phase gives any of @@ -2405,7 +2405,7 @@ namespace MobileGL::MG_Pipe { ++stored->Serial; // record.AccessFlags are the application's REAL mapping flags and this applier does - // not normalise them: the backend reads INVALIDATE_RANGE / INVALIDATE_BUFFER / + // not normalize them: the backend reads INVALIDATE_RANGE / INVALIDATE_BUFFER / // UNSYNCHRONIZED per call to choose its upload shape, and merging them here would take // that choice away from the side that pays for it. if (g_resourceOps != nullptr && g_resourceOps->FlushRange != nullptr) { @@ -2909,20 +2909,20 @@ namespace MobileGL::MG_Pipe { fault = "the framebuffer slot is outside the record table's bound"; } // THE DRAW-BUFFER ARRAY IS AN INDEX INTO THIS RECORD'S OWN Color[], and -1 is NONE. An - // entry outside that range would have the server read a colour attachment the record + // entry outside that range would have the server read a color attachment the record // does not carry: the wire array is 8 wide, the driver's MaxColorAttachments is not // clamped to it, and a truncated record arriving here as a plausible index is exactly // what the framebuffer subsystem's cap refusal exists to prevent upstream. for (Uint32 i = 0; fault == nullptr && i < kMGPipeMaxColorAttachments; ++i) { if (state.DrawBuffers[i] < -1 || state.DrawBuffers[i] >= static_cast(kMGPipeMaxColorAttachments)) { - fault = "a draw-buffer entry names a colour attachment outside the record's own array"; + fault = "a draw-buffer entry names a color attachment outside the record's own array"; } } if (fault != nullptr) { MGP_TRIP_WIRE_REPORT( "MGPipe: " MGP_TRIP_WIRE_TAG( "ProtocolCorruption") " set_framebuffer_state {slot=%u, gen=%u, target=%u}: %s (the record " - "carries %u colour attachments)", + "carries %u color attachments)", state.Fbo.Slot, state.Fbo.Gen, state.Target, fault, kMGPipeMaxColorAttachments); return; } @@ -3466,7 +3466,7 @@ namespace MobileGL::MG_Pipe { // // The server never re-links: SPIR-V and the reflection archive cross, never source, and // GL_LINK_STATUS is answered by the client from its ProgramObject (ARCHITECTURE.md §7). - // The other inputs a backend program is specialised on (framebuffer clamp masks, storage + // The other inputs a backend program is specialized on (framebuffer clamp masks, storage // binding signature, image formats, patch parameters) arrive through other records. // ================================================================================ @@ -3477,7 +3477,7 @@ namespace MobileGL::MG_Pipe { if (desc.Cso.Slot < kMGPipeFirstAllocatableSlot) return; // THE ONE BLOB RULE, over seven blob refs at once. All seven are declared with Size 0 in - // monolith - "this record does not declare its blob" - and the artefacts ride beside the + // monolith - "this record does not declare its blob" - and the artifacts ride beside the // record through the two companion pointers, so a record that declares nothing AND // carries nothing describes a program with no reflection and no SPIR-V, which is not a // program. The declared lengths themselves cross-check nothing here: no other field of @@ -3486,7 +3486,7 @@ namespace MobileGL::MG_Pipe { // the transport that fills those refs in lands with the splitter that owns them. const char* fault = nullptr; if (link == nullptr || spirv == nullptr) { - fault = "the record declares no blobs and carries no artefacts"; + fault = "the record declares no blobs and carries no artifacts"; } else if (desc.GlobalUboSize > kMGPipeMaxGlobalConstantsBytes) { fault = "the default uniform block is larger than any program may declare"; } @@ -3540,7 +3540,7 @@ namespace MobileGL::MG_Pipe { ++record.GlobalConstantsSerial; } record.Live = true; - // The DESCRIPTOR is what is stored, and the artefacts are not: in monolith the backend + // The DESCRIPTOR is what is stored, and the artifacts are not: in monolith the backend // reads the frontend's own archive, and under split the descriptor is what the // deserialised archive is attached to. Either way the applier owns identity, extent and // order, and never content. @@ -3552,7 +3552,7 @@ namespace MobileGL::MG_Pipe { // change (MGPipeApplierReset keeps the CSO table - a program lives in a share group) // and a stale archive is worse than none. // - // AFTER Desc, so a reader that sees the new descriptor sees the artefacts it describes; + // AFTER Desc, so a reader that sees the new descriptor sees the artifacts it describes; // the apply thread is the only writer and the only reader, so ordering here is about // reading this function rather than about memory visibility. record.Archive = Move(archive); diff --git a/MobileGL/MG_Pipe/PipeApply.h b/MobileGL/MG_Pipe/PipeApply.h index 5285b65c..7dc3351a 100644 --- a/MobileGL/MG_Pipe/PipeApply.h +++ b/MobileGL/MG_Pipe/PipeApply.h @@ -21,8 +21,8 @@ // decodes each record and calls the same ones. bind_render_state and set_dynamic_state scatter // their chunks straight into PipeInputs::m_renderState, the block Espryt's SyncRenderState // reads, so the verify comparator checks the assembled block against live state at every read. -// PipeInputs and the program artefact types are only forward-declared (MG_Pipe sits below -// MG_Backend): entry points take artefacts by pointer and a record holds its archive by +// PipeInputs and the program artifact types are only forward-declared (MG_Pipe sits below +// MG_Backend): entry points take artifacts by pointer and a record holds its archive by // SharedPtr, whose deleter is captured where it is built; users include ProgramArtifactsCodec.h. namespace MobileGL::MG_State::GLState { struct LinkArtifacts; @@ -74,7 +74,7 @@ namespace MobileGL::MG_Pipe { void* (*MapPersistent)(MGPipeHandle res, Uint64 size, const void* seedBytes); void (*UnmapPersistent)(MGPipeHandle res); // P5c (tx): the TEXTURE half of the resource family, appended so every positional - // initialiser of the nine P3a members keeps its meaning. TextureSubData is called + // initializer of the nine P3a members keeps its meaning. TextureSubData is called // from ApplyTextureUpload AFTER the gate, the accumulation and the serial, while // `bytes` still names the staged run (SEG_STAGE retires when the record does, so an // adoption anywhere later would read dead bytes - rule C); the backend copies the @@ -330,7 +330,7 @@ namespace MobileGL::MG_Pipe { }; // create/bind/delete_shader_state, plus set_global_constants' per-program half. The record - // stores the descriptor and adopts the link's artefacts as Archive (see + // stores the descriptor and adopts the link's artifacts as Archive (see // MGPipeApplyCreateShaderState). GlobalConstants is bounded by Desc.GlobalUboSize and written // at most once per program per frame, keyed by (ShaderCso, Version). // MGPipeProgramStorageOverride is one entry of set_program_bindings' storage-override tail as @@ -353,12 +353,12 @@ namespace MobileGL::MG_Pipe { Uint64 Serial = 0; // ---- The program archive the record owns ----------------------------------------- - // A snapshot of this link's artefacts, so every reflection read by the program twin is - // of memory the record owns: ProgramObject::Link() replaces the frontend's artefacts in + // A snapshot of this link's artifacts, so every reflection read by the program twin is + // of memory the record owns: ProgramObject::Link() replaces the frontend's artifacts in // place, and a client running ahead may already have relinked. Under a transport the // decoder deserialises it from SEG_STAGE; in one process PipeRoute copies it without the // codec. A SharedPtr because a program-pipeline composite and its stage programs share - // one link's artefacts and the twin holds it across a build. Every create replaces it. + // one link's artifacts and the twin holds it across a build. Every create replaces it. SharedPtr Archive; // ---- P5e's set_program_bindings tails (CONTRACT-P5E.md §1, §5.5) ------------------- @@ -463,7 +463,7 @@ namespace MobileGL::MG_Pipe { // set_framebuffer_state's record, HELD PER FRAMEBUFFER OBJECT and indexed by the handle's // slot (ID-19(b)). It is the one record kind in this file whose object has NO WIRE LIFETIME: - // the catalogue has no framebuffer create and no framebuffer destroy, because a framebuffer + // the catalog has no framebuffer create and no framebuffer destroy, because a framebuffer // is state and set_framebuffer_state is the only call that names one (D-I2). So there is // nothing to mark dead and nothing to refuse against, and a slot is simply OVERWRITTEN by // its successor's record - which is correct rather than merely tolerable, since the record @@ -877,7 +877,7 @@ namespace MobileGL::MG_Pipe { // session's CURRENT CONTEXT's working state bound to its share group's object records; on // every other thread - the client process, the in-process client+server shape, a unit case, // the whole monolith - it is the process-wide applier, which is what it has always been and - // is byte-for-byte the old behaviour. + // is byte-for-byte the old behavior. // // P14: INLINE, because the backends ask it per state read (dozens of times per draw): in a // process that serves no session - the whole monolith - no resolver is installed and the @@ -937,7 +937,7 @@ namespace MobileGL::MG_Pipe { // The observables that make the keying testable without reading a private map: how many // groups one context's session holds, and how many object records the group the CALLING // thread is in holds. Both are the numbers a case asserts on to tell "isolated" from - // "shared" apart from the behaviour they exist to explain. + // "shared" apart from the behavior they exist to explain. Uint64 MGPipeApplierShareGroupCountForTesting(Uint64 sessionKey); // P14 S6: THE SHARE-GROUP BUCKET A {session, context token} PAIR IS FILED UNDER, answered @@ -1166,7 +1166,7 @@ namespace MobileGL::MG_Pipe { // valid for the duration of the call only. The op-table entry may be null. void MGPipeApplyBufferSubDataResident(const MGPSubData& record, const void* bytes); // resource_flush_range: record.AccessFlags are the application's REAL mapping flags, not - // a normalised subset - the backend reads them per call to choose its upload shape. + // a normalized subset - the backend reads them per call to choose its upload shape. void MGPipeApplyResourceFlushRange(const MGPFlushRange& record, const void* bytes); // resource_readback: whole-buffer by contract. The answer travels back through the // reverse channel, and the writeback happens BEFORE the mutation epoch bumps, never @@ -1302,11 +1302,11 @@ namespace MobileGL::MG_Pipe { const MGPProgramStorageOverride* storageOverrides, const char* const* storageOverrideNames); - // create_shader_state. `link` and `spirv` are the program's artefacts and `archive` is the + // create_shader_state. `link` and `spirv` are the program's artifacts and `archive` is the // snapshot the record adopts (a null clears the previous one); desc's blob refs are not // read. Under a transport the decoder passes its deserialised archive and pointers into it; - // in one process PipeRoute copies the frontend's artefacts into a new archive without the - // codec. The verify build round-trips the artefacts through the codec before storing, and a + // in one process PipeRoute copies the frontend's artifacts into a new archive without the + // codec. The verify build round-trips the artifacts through the codec before storing, and a // mismatch is Fatal{PipeVerifyDiffer, "program-archive"}. `archive` has no default so that a // caller holding one cannot silently omit it. void MGPipeApplyCreateShaderState(const MGPProgramDesc& desc, const MG_State::GLState::LinkArtifacts* link, @@ -1328,7 +1328,7 @@ namespace MobileGL::MG_Pipe { // P4a: the named, greppable unmigrated emulations (D-M) // --------------------------------------------------------------------------------- // - // ROADMAP.md's P4a row ends "emulation 在 split 下显式 Fatal 直到 P8". In monolith the + // ROADMAP.md's P4a row ends "emulations are an explicit Fatal under split until P8". In monolith the // code paths keep running exactly as today - the Fatal is a SPLIT-only arm - so this costs // P4a a named call site per unmigrated emulation and nothing else. P5/P8 give it teeth: a // split server that reaches one of these has no client address space to read and must diff --git a/MobileGL/MG_Pipe/PipeCalls.def b/MobileGL/MG_Pipe/PipeCalls.def index cf855b10..51a526e2 100644 --- a/MobileGL/MG_Pipe/PipeCalls.def +++ b/MobileGL/MG_Pipe/PipeCalls.def @@ -190,7 +190,7 @@ /* the client's allocator, both rule-E surfaces. */ \ X(ObjectDeath, MGPHandleOnly, kCtxObject, kNone, kWaitNone) \ /* ---- P5c rv (CONTRACT-P5C.md §5.3), opcode 79: the residual-value record. One POD that ---- */ \ - /* ---- carries every value-class BARRIER_PULLED field left after the set_* catalogue: the ---- */ \ + /* ---- carries every value-class BARRIER_PULLED field left after the set_* catalog: the ---- */ \ /* ---- two texture-unit counters, the 15 per-target touched-buffer-binding counts and the ---- */ \ /* ---- five transform-feedback values. Emitted at validate when any covered value moved ---- */ \ /* ---- (whole-record hash suppression, D11's shape), ACTIVE ONLY with an active transport ---- */ \ @@ -236,7 +236,7 @@ X(BindContext, MGPBindContext, kScreen, kNone, kWaitNone) \ /* ---- APPENDED FOR SHARED IMAGES (docs/archive/notes/anland/plan-ahb-dmabuf.md), ---- */ \ /* ---- opcode 85: allocate / import / release / present / attach of a server-allocated ---- */ \ - /* ---- colour buffer exported as a dma-buf. kScreen: the image table is the server's, and ---- */ \ + /* ---- color buffer exported as a dma-buf. kScreen: the image table is the server's, and ---- */ \ /* ---- present / attach act on the session's current context the way bind_context does. ---- */ \ /* ---- kWaitReply: every operation's answer is acted on (an id, a descriptor, a fence). ---- */ \ /* ---- No MGPipeApply* entry point and no monolith producer. ---- */ \ diff --git a/MobileGL/MG_Pipe/PipeFields.def b/MobileGL/MG_Pipe/PipeFields.def index 0dde83f8..8c73d24c 100644 --- a/MobileGL/MG_Pipe/PipeFields.def +++ b/MobileGL/MG_Pipe/PipeFields.def @@ -345,10 +345,10 @@ // P4a, D-F1: THE PADDING TRAP. SamplerParameters is sizeof == 100 with THREE BYTES OF // TRAILING PADDING (96 bytes of members plus the 1-byte borderColorForm) and had no field // table and no MGP_VERIFY_PAYLOAD_LIST row at all, so MGPSamplerDesc's blob was compared as -// BYTES and MOBILEGL_PIPE_VERIFY could false-differ on uninitialised padding - a coin flip +// BYTES and MOBILEGL_PIPE_VERIFY could false-differ on uninitialized padding - a coin flip // rather than a gate. With this list the comparator sees the sixteen members and the three // bytes can never enter the answer. The client-side CSO cache hashes and memcmp-confirms over -// a ZERO-INITIALISED canonical copy for the same reason, which is the other half of D-F1. +// a ZERO-INITIALIZED canonical copy for the same reason, which is the other half of D-F1. #define MGP_FIELDS_SamplerParameters(F) \ F(wrapS) F(wrapT) F(wrapR) F(minFilter) F(magFilter) F(mipmapMode) F(minLod) F(maxLod) \ F(lodBias) F(maxAnisotropy) F(compareFunc) F(compareMode) F(borderColor) F(borderColorI) \ diff --git a/MobileGL/MG_Pipe/PipeMutation.h b/MobileGL/MG_Pipe/PipeMutation.h index 517b7c98..5f606fe5 100644 --- a/MobileGL/MG_Pipe/PipeMutation.h +++ b/MobileGL/MG_Pipe/PipeMutation.h @@ -149,7 +149,7 @@ namespace MobileGL::MG_Pipe { Bool MGPipeEmitRenderbufferDestroyAndFree(Uint64 lifetimeId); // NO WIRE CALL AT ALL (D-I2). PipeCalls.def has no framebuffer delete, because a // framebuffer is not a resource and is not a CSO - it is STATE, and set_framebuffer_state - // is the only call that names one - and the catalogue is closed, so P4a does not invent a + // is the only call that names one - and the catalog is closed, so P4a does not invent a // row. The handle is minted and freed entirely client-side and this helper does steps 2 // and 3 only. A recycled framebuffer handle is distinguished by Gen, which is inside the // record's ContentHash, so it can never be suppressed against its predecessor's record. @@ -363,7 +363,7 @@ namespace MobileGL::MG_Pipe { // Entry points MGPipeSamplerEmitter must provide, returning void: // EmitSamplerCso(SamplerObject&) - D-F1's content-addressed mint-or-share at // capacity 256, hashed field-wise over a canonical - // zero-initialised copy, behind the version-first + // zero-initialized copy, behind the version-first // skip. The HANDLE RULE FOR THIS KIND IS THE // EMITTER'S, not this file's: two identical // samplers share one CSO, so there is deliberately diff --git a/MobileGL/MG_Pipe/PipeRoute.cpp b/MobileGL/MG_Pipe/PipeRoute.cpp index c964eb4d..e367035c 100644 --- a/MobileGL/MG_Pipe/PipeRoute.cpp +++ b/MobileGL/MG_Pipe/PipeRoute.cpp @@ -12,7 +12,7 @@ // arm is measured against. Three kinds of row do one thing more: rows whose call site waits for // an answer post a reply, the create_shader_state escape builds the record's archive, and the // retired set_residual_value_state row aborts. The tables are installed before main by -// detail::gMonolithTablesInstalled in PipeRoute.h, not by a static initialiser here (a +// detail::gMonolithTablesInstalled in PipeRoute.h, not by a static initializer here (a // static-archive link can drop this object), so no MGP_* thunk needs a null check. #include "PipeRoute.h" @@ -228,7 +228,7 @@ namespace MobileGL::MG_Pipe { MGP_MONO_TAIL(SetSamplerViews, MGPSamplerViews, MGPBoundView) MGP_MONO_TAIL(BindSamplerStates, MGPSamplerStates, MGPipeHandle) MGP_MONO_TAIL(SetShaderImages, MGPShaderImages, MGPImageView) - // P5e (sb, CONTRACT-P5E.md §5.6). Catalogued since P4a with no producer and no + // P5e (sb, CONTRACT-P5E.md §5.6). Cataloged since P4a with no producer and no // consumer; the adapter lands with the applier's body. The generic tail shape fits // because the SECOND tail is absent on every Espryt configuration (HostSpanCount is 0 // while kCapNeedsHostUboBytes is 0, which is the whole of P5). @@ -314,7 +314,7 @@ namespace MobileGL::MG_Pipe { // P13 W4c: MONOLITH'S RECORD ARM READS THE RECORD'S ARCHIVE (ProgramHandleArm), so it // gets one: the link's snapshot, taken here, once per link - the same thing the wire // decodes into the record, without the codec. A copy rather than a borrow, because the - // record is a snapshot of THIS link and the frontend object's artefacts are replaced + // record is a snapshot of THIS link and the frontend object's artifacts are replaced // by the next one while the record may still be in use. if (MG_Config::RecordArmAliasesFrontend() && link != nullptr && spirv != nullptr) { auto archive = MakeShared(); @@ -330,7 +330,7 @@ namespace MobileGL::MG_Pipe { // P5e (pg): NO ARCHIVE ON THIS ARM, and the null is the arm selection rather than a // hole. Under monolith the two companion pointers ARE the frontend's own archive, // the backend twin reads it through its frontend overload (ruling 1 keeps that arm - // token for token), and serialising here to deserialise into the record would put + // token for token), and serializing here to deserialise into the record would put // EncodeProgramArtifacts on the monolith path - which PipeRoute.h's escape note // and PipeApply.h both promise it is not. MGPipeApplyCreateShaderState(*desc, link, spirv, nullptr); diff --git a/MobileGL/MG_Pipe/PipeRoute.h b/MobileGL/MG_Pipe/PipeRoute.h index 1091c59d..fd85d4e4 100644 --- a/MobileGL/MG_Pipe/PipeRoute.h +++ b/MobileGL/MG_Pipe/PipeRoute.h @@ -60,7 +60,7 @@ namespace MobileGL::MG_Pipe { // signature because the monolith arm passes what the wire record does not carry: // ResourceRespecify's `initialBytes` and ResourceFlushRange's `bytes` (sent as resource_subdata // records instead), MapPersistent's `size`, `seedBytes` and void* result, CreateShaderState's - // seven SPIR-V/reflection blobs (monolith never serialises them), SetProgramBindings' tails. + // seven SPIR-V/reflection blobs (monolith never serializes them), SetProgramBindings' tails. struct MGPipeRouteEscapes { Bool (*ResourceRespecify)(const MGPResourceDesc* desc, const void* initialBytes, const MGPRespecifiedLevel* level); @@ -108,7 +108,7 @@ namespace MobileGL::MG_Pipe { namespace detail { // Installs the monolith tables before main in every binary that includes this header. - // A static initialiser in PipeRoute.cpp is not enough: a test binary linking the static + // A static initializer in PipeRoute.cpp is not enough: a test binary linking the static // archive may drop PipeRoute.o (CsoCache.h reaches the tables only through an inline // thunk), leaving the tables null. This inline variable is emitted in each including // translation unit, and its call to MGPipeInstallMonolithTables pulls PipeRoute.o in. @@ -201,7 +201,7 @@ namespace MobileGL::MG_Pipe { MGPReplySlot reply = MGPipeMintReplySlot(); MGP_ResourceSubData(&record, bytes, byteCount, regions, record.RegionCount, &reply); const Bool accepted = MGPipeTakeReplyBool(reply, "resource_subdata"); - // A cancelled wire upload is declined even when no server reply was requested. + // A canceled wire upload is declined even when no server reply was requested. if (MGPipeInstalledArm() == MGPipeRouteArm::kClientWire) return accepted; return MGPipeSubDataWantsItsReply(record) ? accepted : true; } @@ -243,7 +243,7 @@ namespace MobileGL::MG_Pipe { // gates on it); under monolith the row is never produced and the fields keep coming // through the residual fill (G1). The row IS an ordinary routed set_* otherwise - the // monolith adapter exists so the wire emitter's server-role arm has something defined to - // forward to, and the catalogue's null-row accounting (PipeCatalogueTest) counts it. + // forward to, and the catalog's null-row accounting (PipeCatalogueTest) counts it. inline void MGPipeRouteSetContextValues(const MGPContextValues& values) { MGP_SetContextValues(&values); } diff --git a/MobileGL/MG_Pipe/PipeSessionFail.h b/MobileGL/MG_Pipe/PipeSessionFail.h index e487421a..032c957f 100644 --- a/MobileGL/MG_Pipe/PipeSessionFail.h +++ b/MobileGL/MG_Pipe/PipeSessionFail.h @@ -29,7 +29,7 @@ namespace MobileGL::MG_Pipe { // funnels use today, and a third one costs a row here and an arm in the adapter - which is // the point, because that arm is where the choice gets argued. enum class MGPipeFatalFamily : unsigned { - // The Magma wire arms' refusal to honour a verb/shape the split path does not implement. + // The Magma wire arms' refusal to honor a verb/shape the split path does not implement. // Deliberately the SAME word the sites already print: `Magma:` in the detail is what // separates them from the GLES `UnmigratedVerb` deaths, and renaming the family would // invalidate every census number recorded against it since P5b. @@ -109,7 +109,7 @@ namespace MobileGL::MG_Pipe { // ---- THE LATCH TWIN: A LOST GPU DEVICE ENDS ITS SESSION, NOT THE PROCESS ---------------- // - // MGPipeSessionFail is for a verb the backend cannot honour, and it does not return. A device + // MGPipeSessionFail is for a verb the backend cannot honor, and it does not return. A device // loss is different in kind: nothing about the peer's bytes was wrong, the GPU faulted or hung // and the driver reset it, and every session the process serves except the one whose device // went is still healthy. The display server runs every session in ONE process, so dying here @@ -126,7 +126,7 @@ namespace MobileGL::MG_Pipe { // Whether the calling thread's session HAS a latch to raise. A backend that notices its // device lost outside a site that would die anyway (a submit whose failure it used to only // log) latches at once when this is true - so the session stops at its next record however - // the current verb unwinds - and keeps its old behaviour when it is false. + // the current verb unwinds - and keeps its old behavior when it is false. using MGPipeSessionLatchArmedHook = bool (*)(); void MGPipeInstallSessionLatchHook(MGPipeSessionLatchHook hook, MGPipeSessionLatchArmedHook armed); MGPipeSessionLatchHook MGPipeSessionLatchHookInstalled(); diff --git a/MobileGL/MG_Pipe/generated/PipeTables.inc b/MobileGL/MG_Pipe/generated/PipeTables.inc index 248e7f91..6501f993 100644 --- a/MobileGL/MG_Pipe/generated/PipeTables.inc +++ b/MobileGL/MG_Pipe/generated/PipeTables.inc @@ -114,9 +114,9 @@ inline constexpr SizeT kMGPipeCallCount = 85; // A table that is not exactly its call count of function pointers has grown a // member that no generator knows about. static_assert(sizeof(MGPipeScreen) == kMGPipeScreenCallCount * sizeof(void (*)()), - "MGPipeScreen is not exactly its catalogue's function pointers"); + "MGPipeScreen is not exactly its catalog's function pointers"); static_assert(sizeof(MGPipeContext) == kMGPipeContextCallCount * sizeof(void (*)()), - "MGPipeContext is not exactly its catalogue's function pointers"); + "MGPipeContext is not exactly its catalog's function pointers"); static_assert(kMGPipeScreenCallCount + kMGPipeContextCallCount == kMGPipeCallCount); static_assert(kMGPipeCallCount == MGP_CALL_LIST_DOCUMENTED_COUNT, - "the catalogue and its documented count disagree"); + "the catalog and its documented count disagree"); diff --git a/MobileGL/MG_Pipe/generated/PipeWire.inc b/MobileGL/MG_Pipe/generated/PipeWire.inc index b191eb2b..19e15b51 100644 --- a/MobileGL/MG_Pipe/generated/PipeWire.inc +++ b/MobileGL/MG_Pipe/generated/PipeWire.inc @@ -166,8 +166,8 @@ enum class MGPWireOp : Uint16 { // GetCaps and CreateSamplerState came to carry an MGPBlobRef member with no kHasBlob on // their line at all - nothing compared the two, because nothing had both in one place. // -// Index 0 is MGPWireOp::kInvalid and is kNone: the catalogue is 1-based, and an encoder -// that reads flags for an opcode it never got from the catalogue must see the empty set +// Index 0 is MGPWireOp::kInvalid and is kNone: the catalog is 1-based, and an encoder +// that reads flags for an opcode it never got from the catalog must see the empty set // rather than another call's flags. // // kHasBlob here means EXACTLY "the payload owns an MGPBlobRef member". Three calls carry @@ -268,7 +268,7 @@ static_assert(sizeof(kMGPipeCallFlags) / sizeof(kMGPipeCallFlags[0]) == "the flags table and the opcode space disagree"); // The only supported read of the table. Out-of-range is kNone rather than undefined -// behaviour, because the one caller that can pass a bad opcode is a decoder holding bytes +// behavior, because the one caller that can pass a bad opcode is a decoder holding bytes // off a stream, and it must reach its own Fatal{ProtocolCorruption} rather than read past // the array on the way there. inline constexpr Uint32 MGPipeCallFlagsFor(MGPWireOp op) { @@ -277,7 +277,7 @@ inline constexpr Uint32 MGPipeCallFlagsFor(MGPWireOp op) { : static_cast(kNone); } -// The catalogue class of every opcode, indexed the same way; index 0 is kCallClassCount, +// The catalog class of every opcode, indexed the same way; index 0 is kCallClassCount, // never a real class, for the flags table's reason. inline constexpr Uint8 kMGPipeCallClasses[static_cast(MGPWireOp::kOpCount)] = { /* 0 */ static_cast(kCallClassCount), @@ -381,7 +381,7 @@ inline constexpr MGPipeCallClass MGPipeCallClassFor(MGPWireOp op) { // P5e (2.2): THE WAIT CLASS OF EVERY OPCODE, indexed the same way. // Index 0 is kWaitClassCount - never a real class - for the flags table's reason: the one -// caller that can pass an opcode this catalogue never produced is a decoder holding bytes off +// caller that can pass an opcode this catalog never produced is a decoder holding bytes off // a stream, and it must reach its own Fatal{ProtocolCorruption} rather than a wait decision. // // This is the STATIC HALF of MGPipeBarriered(op, payload, applierState), the predicate the emit @@ -489,7 +489,7 @@ inline constexpr MGPipeWaitClass MGPipeWaitClassFor(MGPWireOp op) { } // THE COLUMN'S OWN INVARIANT, stated in C++ as well as in the generator: a reply-slot row -// waits for its reply and a waiting row owns a slot. gen_pipe.py refuses a catalogue where the +// waits for its reply and a waiting row owns a slot. gen_pipe.py refuses a catalog where the // two disagree, and this is the same statement where a reader of the generated table will look // for it - a kReplySlot row that did not wait would run on and read a slot nobody had posted // into, and a kWaitReply row with no slot would block on an answer nobody posts. @@ -504,7 +504,7 @@ static_assert(MGPipeWaitClassFor(MGPWireOp::ApplierReset) == kWaitApplied, static_assert(MGPipeWaitClassFor(MGPWireOp::ReadPixels) == kWaitReply, "a readback's answer is not derivable (R-5)"); -// Spot checks the generator states about its own output, so that a catalogue edit that +// Spot checks the generator states about its own output, so that a catalog edit that // silently drops a flag is a build break here and not a wrong decode six packages away. static_assert(MGPipeCallFlagsFor(MGPWireOp::kInvalid) == static_cast(kNone), "opcode 0 is not a call and carries no flags"); @@ -1259,9 +1259,9 @@ inline MGPipeWireRecordApplyFn gMGPipeWireRecordApply = nullptr; // record's own count fields and require it to EQUAL MGPWireRecHeader::Size - belongs to the // decoder, which has the payload (MG_Remote/Wire's MGPipeWireRecordLayout, P5 w1). // -// The switch and the opcode enum come from the same list, so a call added to the catalogue +// The switch and the opcode enum come from the same list, so a call added to the catalog // cannot be forgotten here; the default arm is for the opcode that never came from this -// catalogue at all - a byte off a corrupt stream - and it is fatal for the same reason the +// catalog at all - a byte off a corrupt stream - and it is fatal for the same reason the // bounds check is. // // With no decoder installed - every monolith build, and a split build before diff --git a/MobileGL/MG_Pipe/generated/PipeWireLayout.inc b/MobileGL/MG_Pipe/generated/PipeWireLayout.inc index df514012..0a42b5ef 100644 --- a/MobileGL/MG_Pipe/generated/PipeWireLayout.inc +++ b/MobileGL/MG_Pipe/generated/PipeWireLayout.inc @@ -6,7 +6,7 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header -// P6.5: wire layout and ordered catalogue. +// P6.5: wire layout and ordered catalog. // // GENERATED by scripts/gen_pipe.py from PipeFields.def and PipeCalls.def - DO NOT EDIT. // Regenerate with `python3 scripts/gen_pipe.py`; CI runs it and diffs the result. diff --git a/MobileGL/MG_Remote/CapsCodec.cpp b/MobileGL/MG_Remote/CapsCodec.cpp index 4c192c0b..94b86469 100644 --- a/MobileGL/MG_Remote/CapsCodec.cpp +++ b/MobileGL/MG_Remote/CapsCodec.cpp @@ -249,7 +249,7 @@ namespace MobileGL::MG_Remote { if (targets != MG_Backend::kFormatCapabilityTargetCount || formats != MG_Backend::kFormatCapabilityFormatCount) { // Not a corrupt stream: a peer whose TextureTarget or TextureInternalFormat enum - // is a different size. Reading it anyway shears every cell onto a neighbouring + // is a different size. Reading it anyway shears every cell onto a neighboring // format, which is exactly the failure the ABI fingerprint exists to make loud. MGLOG_E("MG_Remote caps: format-capability blob is %ux%u, this build is %llux%llu", targets, formats, static_cast(MG_Backend::kFormatCapabilityTargetCount), diff --git a/MobileGL/MG_Remote/Client/BackendObject_Remote.cpp b/MobileGL/MG_Remote/Client/BackendObject_Remote.cpp index 520cc7e5..bd8900ff 100644 --- a/MobileGL/MG_Remote/Client/BackendObject_Remote.cpp +++ b/MobileGL/MG_Remote/Client/BackendObject_Remote.cpp @@ -79,9 +79,9 @@ namespace MobileGL::MG_Remote::Client { // ---- the eight pure virtuals ---------------------------------------------------------- void BackendObject_Remote::Initialize() { - // NOT FORWARDED. The server's own BackendObject_DirectGLES is created and initialised + // NOT FORWARDED. The server's own BackendObject_DirectGLES is created and initialized // by v1's ServerLoop, on the apply thread, before this object exists; forwarding here - // would be a second Initialize() on an already-initialised backend. What this call + // would be a second Initialize() on an already-initialized backend. What this call // does is drain whatever the handshake left and take the caps that came with it. if (ClientSession* session = ClientSession::Active()) { session->PumpControlPlane(); @@ -184,7 +184,7 @@ namespace MobileGL::MG_Remote::Client { // ---- the nine EGL lifecycle virtuals --------------------------------------------------- // // FORWARD FIRST, THEN RUN THE BASE. The server has to own the context before the client's - // base class latches "the surface is initialised" and calls InitCapabilities, because + // base class latches "the surface is initialized" and calls InitCapabilities, because // InitCapabilities' answer comes from a snapshot the server can only publish once its own // InitCapabilities has run. @@ -388,7 +388,7 @@ namespace MobileGL::MG_Remote::Client { Bool BackendObject_Remote::MakeEGLCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { // FORWARD FIRST, THEN RUN THE BASE. The server has to own the context before the base - // class latches "the surface is initialised" and calls InitCapabilities, because + // class latches "the surface is initialized" and calls InitCapabilities, because // InitCapabilities' answer comes from a snapshot the server can only publish once its // own InitCapabilities has run - and ServerMakeEGLCurrent is what publishes it. WaitForApplyBeforeEglForwarder("MakeEGLCurrent"); @@ -415,7 +415,7 @@ namespace MobileGL::MG_Remote::Client { // republishes the caps snapshot on every call (ServerLoop.cpp:613-628), but the base // class only runs InitCapabilities - the one place that pumps and refreshes - on the // FIRST make-current per surface (EGLSurfaceRegistry::MakeCurrent). A repeated make-current - // onto an already-initialised surface therefore left the client mirror one generation + // onto an already-initialized surface therefore left the client mirror one generation // behind while unpumped snapshots accumulated, so a cap getter or a shader compile before // the next Present read the prior mirror. Adopting here closes that: "a second snapshot // arrival IS the invalidation" (R-12) now holds AT the make-current that caused it. It is diff --git a/MobileGL/MG_Remote/Client/CapsMirror.cpp b/MobileGL/MG_Remote/Client/CapsMirror.cpp index 810fa2fe..95569bf2 100644 --- a/MobileGL/MG_Remote/Client/CapsMirror.cpp +++ b/MobileGL/MG_Remote/Client/CapsMirror.cpp @@ -218,7 +218,7 @@ namespace MobileGL::MG_Remote::Client { return; } // NOT MGLOG_W AND CARRY ON. The whole defect this closes is that carrying on was - // indistinguishable, in every downstream artefact, from a server that genuinely + // indistinguishable, in every downstream artifact, from a server that genuinely // consumes nothing: same absence of records, same cleared dirty flags, same green // lane. A death names the family, publishes a SessionFault to a peer if one is // connected, and lands in the census like every other one. diff --git a/MobileGL/MG_Remote/Client/ClientSession.cpp b/MobileGL/MG_Remote/Client/ClientSession.cpp index 61a14a98..2191ab22 100644 --- a/MobileGL/MG_Remote/Client/ClientSession.cpp +++ b/MobileGL/MG_Remote/Client/ClientSession.cpp @@ -396,7 +396,7 @@ namespace MobileGL::MG_Remote::Client { static_cast(defaultFBOInfo->stencilAttachment.get()); if (info.Width != 0 && info.Height != 0) { // The SWAPCHAIN's publication shape: an extent-carrying event. Reproduces - // SwapchainObject's monolith writes statement for statement - colour storage + // SwapchainObject's monolith writes statement for statement - color storage // at the extent, depth/stencil format then storage - because // FramebufferObject::CheckCompleteness requires every attachment to agree. const Int extentWidth = static_cast(info.Width); @@ -419,7 +419,7 @@ namespace MobileGL::MG_Remote::Client { } else { // The DirectGLES publication shape: FORMAT ONLY, Width/Height == 0. The // placeholder's 512x512 extent is deliberately left alone - all three - // attachments share it, and resizing depth/stencil without colour would + // attachments share it, and resizing depth/stencil without color would // report the default framebuffer incomplete. if (depthTex != nullptr) depthTex->SetInternalFormat(format); if (stencilTex != nullptr) stencilTex->SetInternalFormat(format); @@ -1515,11 +1515,11 @@ namespace MobileGL::MG_Remote::Client { } if (received != MOBILEGL_OK) SessionFail(MGFatalFamily::ProtocolCorruption, - "MGPipe: Fatal{ProtocolCorruption, LogFlush} no acknowledgement rc=%d", received); + "MGPipe: Fatal{ProtocolCorruption, LogFlush} no acknowledgment rc=%d", received); const auto* reply = ParseEnvelope(bytes); if (!reply) SessionFail(MGFatalFamily::ProtocolCorruption, - "MGPipe: Fatal{ProtocolCorruption, LogFlush} malformed acknowledgement"); + "MGPipe: Fatal{ProtocolCorruption, LogFlush} malformed acknowledgment"); if (const auto* ack = reply->msg_as_LogFlush()) { if (!ack->ack() || ack->seq() != seq) { SessionFail(MGFatalFamily::ProtocolCorruption, @@ -1555,7 +1555,7 @@ namespace MobileGL::MG_Remote::Client { } // ONE CONTROL OP AT A TIME. The twelve forwarders are already - // caller-serialised on the server's m_callerMutex under inproc; the same + // caller-serialized on the server's m_callerMutex under inproc; the same // discipline has to hold here or two replies race for one correlation. const std::lock_guard lock(m_remoteControlMutex); // The whole op - prefix drain, reply, event delivery - runs on one budget: the cold-start @@ -2258,11 +2258,11 @@ namespace MobileGL::MG_Remote::Client { // Does this row own a reply slot? kMGPipeCallFlags IS THE SINGLE SOURCE OF TRUTH // (R-16 / ID-31) - fourteen rows now, because the four Bool acceptance entry points - // gained the flag. Asking the catalogue rather than the caller is what stops a caller + // gained the flag. Asking the catalog rather than the caller is what stops a caller // that forgot to pass a buffer from silently turning an answer into a guess. // // P5e (ra) ADDS ONE CALLER-SIDE CONJUNCT AND NO SECOND SOURCE OF TRUTH: `wantReply`. - // The catalogue still says which rows CARRY a slot; a caller that passes false says it + // The catalog still says which rows CARRY a slot; a caller that passes false says it // will not read this one (resource_subdata's buffer half, §2.5 - the only such caller). // The server posts either way, so the wire is unchanged and the row keeps its flag. @@ -2483,7 +2483,7 @@ namespace MobileGL::MG_Remote::Client { void ClientSession::WaitForApplyToCatchUp(const char* why) { #if MOBILEGL_BUILD_DISAGGREGATED - // A NO-OP WITHOUT RUN-AHEAD, and that is not an optimisation: under lockstep the + // A NO-OP WITHOUT RUN-AHEAD, and that is not an optimization: under lockstep the // client already waited for every record it published, so appliedSeq is at // LastPublishedSeq by construction and a second wait would only add a park on a // watermark that is already reached. @@ -3029,7 +3029,7 @@ namespace MobileGL::MG_Remote::Client { }; Int32 status = Wire::ReplySink::kStatusError; EmitAndWait(MG_Pipe::MGPWireOp::MapPersistent, &handle, sizeof(handle), nullptr, 0, nullptr, 0, &status); - m_prePublish = nullptr; // a cancelled encode never ran it + m_prePublish = nullptr; // a canceled encode never ran it #if !defined(_WIN32) ::close(hop); #endif diff --git a/MobileGL/MG_Remote/Client/ClientSession.h b/MobileGL/MG_Remote/Client/ClientSession.h index b081da18..eb33cba8 100644 --- a/MobileGL/MG_Remote/Client/ClientSession.h +++ b/MobileGL/MG_Remote/Client/ClientSession.h @@ -214,13 +214,13 @@ namespace MobileGL::MG_Remote::Client { // one with a single WireTail; the barrier policy lives in exactly one body. A distinct // name rather than an overload, because `nullptr, 0` would match both. // P5e (ra, CONTRACT-P5E §2.5): `wantReply` is the ONE caller-side relaxation of the - // catalogue's reply rule, and it exists for exactly one row - resource_subdata's + // catalog's reply rule, and it exists for exactly one row - resource_subdata's // BUFFER half, whose Bool the only caller discards (PipeFill.cpp's // MGPipeEmitResourceSubData). The row keeps kReplySlot on the wire (the server still // posts; an unread slot is harmless, ReplySlotPool's seq-stamped slots), so nothing about the // protocol moves - what moves is that under run-ahead this client neither waits for // the answer nor reads it, which is what makes the 64 KB persistent-map push - // fire-and-forget instead of a hidden round trip per block. It is NOT a licence to + // fire-and-forget instead of a hidden round trip per block. It is NOT a license to // skip an answer a caller uses: R-5 still forbids re-deriving one locally, and every // other kReplySlot row passes true (the default) and waits. Uint64 EmitAndWaitTails(MG_Pipe::MGPWireOp op, const void* payload, Uint64 payloadBytes, @@ -462,7 +462,7 @@ namespace MobileGL::MG_Remote::Client { // this immediately before each EmitAndWait(MGPWireOp::ReadPixels, ...), with that // band's box, its Format/Type enums and the DstSize it computed - and, when not even one // pixel fits a reply, once for that one pixel instead of emitting; the server's Post - // keeps its own refusal as the last line of defence, but that one fires on the apply + // keeps its own refusal as the last line of defense, but that one fires on the apply // thread with the record already on the wire, where all the client sees is a hang. void RequireReadPixelsReplyFits(Uint32 width, Uint32 height, Uint32 format, Uint32 type, Uint64 bytes) const; diff --git a/MobileGL/MG_Remote/Client/EmitTables.h b/MobileGL/MG_Remote/Client/EmitTables.h index 22292196..1afa6112 100644 --- a/MobileGL/MG_Remote/Client/EmitTables.h +++ b/MobileGL/MG_Remote/Client/EmitTables.h @@ -20,7 +20,7 @@ #include // P5b: the clear discriminants below alias MGPipeTypes.h's (CONTRACT-P5B.md f1). The header -// was already in this file's closure through BackendObject.h's neighbours; naming it makes +// was already in this file's closure through BackendObject.h's neighbors; naming it makes // the dependency the aliases have explicit. #include #include @@ -77,7 +77,7 @@ namespace MobileGL::MG_Remote::Client { // The other two thirds of the census, so a case can assert the WHOLE partition rather than // only the half that emits. CONTRACT-P5.md §7's three classes are 2 + 5 + 64, and // EmitTables.cpp static_asserts that they sum to kRemoteEmitSlotCount: a slot that quietly - // changes class shows up as a build break in the sum, not as a silent behaviour change. + // changes class shows up as a build break in the sum, not as a silent behavior change. Uint32 LocallyAnsweredSlotCount(); // class A - answered from the caps mirror, R-15 Uint32 UnmigratedSlotCount(); // class C - Fatal{UnmigratedVerb} diff --git a/MobileGL/MG_Remote/Client/GpuWritePending.cpp b/MobileGL/MG_Remote/Client/GpuWritePending.cpp index 4fbc618e..cd71b148 100644 --- a/MobileGL/MG_Remote/Client/GpuWritePending.cpp +++ b/MobileGL/MG_Remote/Client/GpuWritePending.cpp @@ -61,7 +61,7 @@ namespace MobileGL::MG_Remote::Client { SizeT MGPipeStageChunkBytes() { // The server role's own uploads run the monolith adapter (RunsAsTheServerRole's comment // in WireTables.h): cutting them would change how many calls the server's own backend - // sees for one application call, which is a monolith behaviour change on the apply + // sees for one application call, which is a monolith behavior change on the apply // thread and not this emitter's to make. if (MG_Config::Transport == MG_Config::TransportMode::Monolith) return 0; if (RunsAsTheServerRole()) return 0; diff --git a/MobileGL/MG_Remote/Client/WireTables.cpp b/MobileGL/MG_Remote/Client/WireTables.cpp index 4ad4010d..a24dcccc 100644 --- a/MobileGL/MG_Remote/Client/WireTables.cpp +++ b/MobileGL/MG_Remote/Client/WireTables.cpp @@ -36,7 +36,7 @@ #include #include // P5e (pg): ID-87 asks this package for bytes-per-link measured rather than argued, and the -// archive's byte count exists exactly once - here, where it is serialised. +// archive's byte count exists exactly once - here, where it is serialized. #include // P12: kDefaultReplySlotCount, because the create window's ceiling is derived from the pool it // shares rather than from a number written twice (see kCreateWindowMax below). @@ -589,7 +589,7 @@ namespace MobileGL::MG_Remote::Client { session.EmitAndWaitTails(MGPWireOp::ResourceCreate, payload, sizeof(*payload), nullptr, 0, nullptr, 0, &status, nullptr, /*wantReply=*/false, /*willReadReply=*/true); if (seq == Wire::kInvalidSeq) { - // Cancelled: there is no ordinal to read an answer from, and the caller must NOT + // Canceled: there is no ordinal to read an answer from, and the caller must NOT // latch an object the record never described. MG_Pipe::MGPipePostReply(*reply, Wire::ReplySink::kStatusDeclined, 0u); ++g_emitted; @@ -858,12 +858,12 @@ namespace MobileGL::MG_Remote::Client { "MGPipe: Fatal{ArtefactsMissing, \"create_shader_state\"} - the record's " "two typed companions are null. Under monolith the applier reads the " "modules out of spirv->generatedSpirv; under split there is nothing to " - "serialise, and emitting the record anyway would create a CSO with no " + "serialize, and emitting the record anyway would create a CSO with no " "code"); } // EncodeProgramArchive APPENDS and never fails - everything it walks is owned // plain data - so an empty archive means the two structs themselves were empty, - // which is a linked program with no artefacts and is not a codec question. + // which is a linked program with no artifacts and is not a codec question. // // P5e (pg): THE FRAMED form, so the record's own copy on the far side can pair each // module with its stage. The bare EncodeProgramArtifacts is still what the verify @@ -881,7 +881,7 @@ namespace MobileGL::MG_Remote::Client { if (archive.empty()) { SessionFail(MGFatalFamily::ArchiveEmpty, "MGPipe: Fatal{ArchiveEmpty, \"create_shader_state\"} - the program's " - "artefacts serialised to nothing"); + "artifacts serialized to nothing"); } MG_Pipe::MGPProgramDesc record = *desc; for (Uint32 i = 0; i < 6; ++i) diff --git a/MobileGL/MG_Remote/FatalFunnel.h b/MobileGL/MG_Remote/FatalFunnel.h index addf7c02..22a5eaf6 100644 --- a/MobileGL/MG_Remote/FatalFunnel.h +++ b/MobileGL/MG_Remote/FatalFunnel.h @@ -69,7 +69,7 @@ namespace MobileGL::MG_Remote { ::std::uint64_t SessionLatchCount(); // ---- one latch domain per served session --------------------------------------------- - // The latch is per session so one peer's bad bytes cannot stop a neighbour in the same + // The latch is per session so one peer's bad bytes cannot stop a neighbor in the same // process: its readers (the apply loop, DrainRing, ServerMain's control loop) run on the // session's own threads. SessionRuntime opens a domain per served session and // ThreadSessionScope binds both of its threads to it; an unbound thread uses domain 0, the diff --git a/MobileGL/MG_Remote/Server/ApplyThreadPolicy.h b/MobileGL/MG_Remote/Server/ApplyThreadPolicy.h index 81b16663..00190d8a 100644 --- a/MobileGL/MG_Remote/Server/ApplyThreadPolicy.h +++ b/MobileGL/MG_Remote/Server/ApplyThreadPolicy.h @@ -142,7 +142,7 @@ namespace MobileGL::MG_Remote::Server { const unsigned long long parsed = std::strtoull(affinity, &end, 0); if (end == affinity || (end != nullptr && *end != '\0')) { policy.recognised = false; - policy.rule = "unrecognised"; + policy.rule = "unrecognized"; return policy; } policy.requestedMask = static_cast(parsed); diff --git a/MobileGL/MG_Remote/Server/PipeApplier.cpp b/MobileGL/MG_Remote/Server/PipeApplier.cpp index 1d889e4b..97e3a00c 100644 --- a/MobileGL/MG_Remote/Server/PipeApplier.cpp +++ b/MobileGL/MG_Remote/Server/PipeApplier.cpp @@ -448,8 +448,8 @@ namespace MobileGL::MG_Remote::Server { return false; } SI::ImageRef image = SI::Identify(fd, op.Width, op.Height, op.Format, why); - // YUV: the planes and colour hints ride in Damage (MGPImportPlaneWord). A buffer this - // server did not allocate is taken too, through the labelled CPU-copy fallback + // YUV: the planes and color hints ride in Damage (MGPImportPlaneWord). A buffer this + // server did not allocate is taken too, through the labeled CPU-copy fallback // (SharedImageRegistry.h, Image::ForeignSource); RGBA ones never are. const Bool yuv = SI::FourccIsYuv(op.Format) && op.DamageCount == MG_Pipe::kMGPImportPlaneWords; if (image == nullptr && yuv) { @@ -696,7 +696,7 @@ namespace MobileGL::MG_Remote::Server { // per-verb stamp refreshes it against the served-context serial). A no-op unless the // dual-block rehearsal is armed; without it the server block's ContextIdentity() stays // nullptr and the backend's identity-keyed memo caches read that as a HIT on their - // zero-initialised slot - an unnamed null dereference instead of a named marker. + // zero-initialized slot - an unnamed null dereference instead of a named marker. MG_Pipe::MGPipeServerBlockNoteIdentity(); m_attached = true; } diff --git a/MobileGL/MG_Remote/Server/ServerDisplay.cpp b/MobileGL/MG_Remote/Server/ServerDisplay.cpp index c5e67d69..c76d61bf 100644 --- a/MobileGL/MG_Remote/Server/ServerDisplay.cpp +++ b/MobileGL/MG_Remote/Server/ServerDisplay.cpp @@ -39,7 +39,7 @@ namespace MobileGL::MG_Remote::Server { case ServerWindowAcquire::NoWindow: return "NoWindow"; case ServerWindowAcquire::Cancelled: - return "Cancelled"; + return "Canceled"; case ServerWindowAcquire::Interrupted: return "Interrupted"; case ServerWindowAcquire::LeasedElsewhere: diff --git a/MobileGL/MG_Remote/Server/ServerDisplay.h b/MobileGL/MG_Remote/Server/ServerDisplay.h index e9d2b1c1..d424e367 100644 --- a/MobileGL/MG_Remote/Server/ServerDisplay.h +++ b/MobileGL/MG_Remote/Server/ServerDisplay.h @@ -43,7 +43,7 @@ namespace MobileGL::MG_Remote::Server { // The leased window changed size (surfaceChanged of the SAME window: the app's layout moved it). // Same rules: called with the display's lock held; the holder reads the new extent with WindowExtent. using ServerWindowResizedHook = void (*)(void* holder); - // Asked about every 50 ms while AcquireFor waits; true ends the wait (Cancelled). + // Asked about every 50 ms while AcquireFor waits; true ends the wait (Canceled). using ServerWindowWaitCancel = Bool (*)(void* user); struct ServerWindowLease { diff --git a/MobileGL/MG_Remote/Server/ServerLoop.cpp b/MobileGL/MG_Remote/Server/ServerLoop.cpp index bef7e72b..de113844 100644 --- a/MobileGL/MG_Remote/Server/ServerLoop.cpp +++ b/MobileGL/MG_Remote/Server/ServerLoop.cpp @@ -53,7 +53,7 @@ namespace MobileGL::MG_Remote::Server { // owned the backend, and a texture bind was skipped because the shadow described the // other session's context. So an apply thread holds the turn while it does backend work // (control requests, a drain batch, fence reports, teardown) and gives it up before it - // parks. FIFO, so a session with a busy ring cannot starve its neighbours; reentrant for + // parks. FIFO, so a session with a busy ring cannot starve its neighbors; reentrant for // the thread that holds it. When the turn moves to a different thread the backend takes // ownership for it and drops its binding shadows (DirectGLES::OnBackendTurnHandoff). class BackendTurnLock { @@ -270,7 +270,7 @@ namespace MobileGL::MG_Remote::Server { } if (applied == 0) return 0; if (sched_setaffinity(0, sizeof(set), &set) != 0) return 0; - // Read back the mask the kernel really honoured. This is the codex-11 fix: the log + // Read back the mask the kernel really honored. This is the codex-11 fix: the log // and ResolvedAffinityMask() report the EFFECTIVE set, so a request the cpuset trimmed // is visible as a smaller resolved mask rather than as a lie that matched the request. cpu_set_t effective; @@ -764,7 +764,7 @@ namespace MobileGL::MG_Remote::Server { if (ready()) continue; } - // Never park holding the turn: a neighbour session may be waiting for it. + // Never park holding the turn: a neighbor session may be waiting for it. turn.reset(); const Uint64 waits = m_parks.fetch_add(1, std::memory_order_acq_rel) + 1; // THE WAIT LEDGER'S SERVER HALF (P5d round 3, package T item 4). The client may not @@ -1096,7 +1096,7 @@ namespace MobileGL::MG_Remote::Server { // to Present on the apply thread. Their difference is everything that is NOT applying: // waiting on the ring for the next record, retiring, and the socket. So one line answers // "is the phone CPU-bound, or is it waiting for the client?" without a profiler, which is - // the question the next optimisation has to be chosen from. + // the question the next optimization has to be chosen from. // // FUNCTION-LOCAL STATIC BECAUSE THE FRAME DOES NOT FIT IN ONE DrainRing CALL: records // trickle in, so a frame spans many drains, and state that reset per drain would measure a @@ -1576,7 +1576,7 @@ namespace MobileGL::MG_Remote::Server { // // PH-1 (3): false = the refusal latched (an armed spawn / TCP session child, where the // frame's values came off the wire through SurfaceOpCodec). Under spawn the codec has - // already mapped the wire WindowKind onto a legal tag, so this arm is defence in depth + // already mapped the wire WindowKind onto a legal tag, so this arm is defense in depth // there; unarmed it still dies. Bool WindowBackendFromFrameValue(Int value, MG_Backend::WindowBackend* out) { if (value < static_cast(MG_Backend::WindowBackend::Unknown) || @@ -1739,7 +1739,7 @@ namespace MobileGL::MG_Remote::Server { // MakeEGLCurrent), and the native bind below resolves the context through the session's // current token - which still names whatever another thread bound last, since this // thread's own bind_context follows the frame. Bound first, so the surface is made - // current with ITS context and not attached to a neighbour's. A frame from a client + // current with ITS context and not attached to a neighbor's. A frame from a client // that sends a handle names no token and leaves the binding alone. if (m_session != nullptr && frame.context != 0) (void)m_session->BindContext(frame.context); const MakeCurrentOutcome outcome = ApplyMakeCurrent( @@ -1905,7 +1905,7 @@ namespace MobileGL::MG_Remote::Server { // refuses None), so reaching this line means the slot's bytes were not written by the // poster at all - the ring's Fatal{ProtocolCorruption} discipline, one channel over. // PH-1 (3): latched in an armed session child (under spawn SurfaceOpCodec has already - // refused an unknown wire kind, so this is defence in depth); unarmed it dies. + // refused an unknown wire kind, so this is defense in depth); unarmed it dies. frame.ok = false; (void)SessionLatch(MGFatalFamily::ProtocolCorruption, "MGPipe: Fatal{ProtocolCorruption, \"SurfaceOp.kind\"} - the control slot held " @@ -1956,7 +1956,7 @@ namespace MobileGL::MG_Remote::Server { void ServerLoop::ServerWindowAttachedThunk(void* self) { auto* loop = static_cast(self); // As the lost hook. Called under the display's lock while this loop is registered as suspended, - // and the registration is cancelled (under that lock) before the apply thread exits and before + // and the registration is canceled (under that lock) before the apply thread exits and before // Stop() lets go of m_session. loop->m_windowRequests.fetch_or(kWindowAttached, std::memory_order_acq_rel); if (loop->m_session != nullptr && loop->m_session->DataLink() != nullptr) { diff --git a/MobileGL/MG_Remote/Server/ServerLoop.h b/MobileGL/MG_Remote/Server/ServerLoop.h index 105ec810..82362de3 100644 --- a/MobileGL/MG_Remote/Server/ServerLoop.h +++ b/MobileGL/MG_Remote/Server/ServerLoop.h @@ -246,7 +246,7 @@ namespace MobileGL::MG_Remote::Server { // a release without forwarding it, and returns whether a native bind happened so the // caller (ServerMakeEGLCurrent) knows whether to re-publish the caps snapshot (R-12). struct MakeCurrentOutcome { - Bool ok = false; // the request was honoured + Bool ok = false; // the request was honored Bool boundNatively = false; // a native eglMakeCurrent ran (=> republish caps) }; MakeCurrentOutcome ApplyMakeCurrent(MG_Backend::BackendObject* backend, EGLDisplay dpy, EGLSurface draw, @@ -429,10 +429,10 @@ namespace MobileGL::MG_Remote::Server { UniquePtr m_backend; // The blocking control channel. ONE slot, because the verb barrier already leaves one - // client thread runnable at a time; m_callerMutex serialises anything that is not. + // client thread runnable at a time; m_callerMutex serializes anything that is not. // The slot carries ONE SurfaceControlFrame BY VALUE (P5f, package fc) - no function // pointer, no address of caller storage. The poster's frame is copied in at publish and - // the dispatch's reply half is copied back over it before m_controlDone is signalled. + // the dispatch's reply half is copied back over it before m_controlDone is signaled. std::mutex m_callerMutex; std::mutex m_controlMutex; // THE MAILBOX'S ONE-BIT SHADOW, and the only field of it the idle poll may read. diff --git a/MobileGL/MG_Remote/Server/ServerMain.cpp b/MobileGL/MG_Remote/Server/ServerMain.cpp index ac4eeb61..7f690bb0 100644 --- a/MobileGL/MG_Remote/Server/ServerMain.cpp +++ b/MobileGL/MG_Remote/Server/ServerMain.cpp @@ -857,7 +857,7 @@ namespace { WireLogError("MG_Remote server: session pid=%d reaped signal=%d sessionsFaulted=%lu", reaped, WTERMSIG(status), sessionsFaulted); } else { - // Neither exited nor signalled: WUNTRACED/WCONTINUED are not passed, so this is a status + // Neither exited nor signaled: WUNTRACED/WCONTINUED are not passed, so this is a status // this build does not understand. Counted as a fault rather than silently ignored. ++sessionsFaulted; WireLogError("MG_Remote server: session pid=%d reaped status=0x%x sessionsFaulted=%lu", reaped, status, diff --git a/MobileGL/MG_Remote/Server/ServerSession.cpp b/MobileGL/MG_Remote/Server/ServerSession.cpp index 3856d990..6c305c0b 100644 --- a/MobileGL/MG_Remote/Server/ServerSession.cpp +++ b/MobileGL/MG_Remote/Server/ServerSession.cpp @@ -143,7 +143,7 @@ namespace MobileGL::MG_Remote::Server { // MOBILEGL_IPC_RING_MB / MOBILEGL_IPC_STAGE_MB, actually applied. // // The first version of this file called this only `if (m_sizes.CmdBytes == 0)`, and - // SessionSegmentSizes has a default member initialiser of 8 MiB, so the condition was + // SessionSegmentSizes has a default member initializer of 8 MiB, so the condition was // never true and the whole function was dead: ConfigLoader parsed both knobs, echoed // them into the config line, and the session mapped 8/32 MiB regardless. Config.h's // own comment four lines above the declaration is the statement of that bug - "an diff --git a/MobileGL/MG_Remote/Server/SharedImageRegistry.cpp b/MobileGL/MG_Remote/Server/SharedImageRegistry.cpp index 9ece5c14..5ae42c2d 100644 --- a/MobileGL/MG_Remote/Server/SharedImageRegistry.cpp +++ b/MobileGL/MG_Remote/Server/SharedImageRegistry.cpp @@ -665,7 +665,7 @@ namespace MobileGL::MG_Remote::Server::SharedImages { return live; } - // ---- synchronisation ------------------------------------------------------------------------ + // ---- synchronization ------------------------------------------------------------------------ namespace SyncFile { Bool Signaled(int fd) { diff --git a/MobileGL/MG_Remote/Server/SharedImageRegistry.h b/MobileGL/MG_Remote/Server/SharedImageRegistry.h index 049ff8f2..953d3ad4 100644 --- a/MobileGL/MG_Remote/Server/SharedImageRegistry.h +++ b/MobileGL/MG_Remote/Server/SharedImageRegistry.h @@ -6,7 +6,7 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header -// SHARED IMAGES: colour buffers the server allocates and hands to clients as dma-buf descriptors, +// SHARED IMAGES: color buffers the server allocates and hands to clients as dma-buf descriptors, // so a frame one client renders can be sampled by another (a Wayland window by its compositor) // without leaving GPU memory. // @@ -94,7 +94,7 @@ namespace MobileGL::MG_Remote::Server::SharedImages { Uint64 IdentityDev = 0; Uint64 IdentityIno = 0; - // SYNCHRONISATION, as sync_file descriptors (-1 = nothing pending). An image has one + // SYNCHRONIZATION, as sync_file descriptors (-1 = nothing pending). An image has one // writer at a time (the client session presenting into it) and any number of readers (a // compositor session sampling it). Guarded by SyncMutex; reached only through the // functions below, which is why these are mutable on an otherwise immutable record. @@ -164,7 +164,7 @@ namespace MobileGL::MG_Remote::Server::SharedImages { // image that is not foreign: there is nothing to do. Bool RefreshForeign(const Image& image, std::string& why); - // The colour hints a YUV image is converted with. + // The color hints a YUV image is converted with. void SetYuvHints(const Image& image, const Yuv::Hints& hints); Yuv::Hints GetYuvHints(const Image& image); @@ -174,7 +174,7 @@ namespace MobileGL::MG_Remote::Server::SharedImages { // Live images, for tests and diagnostics. SizeT LiveCount(); - // ---- synchronisation --------------- + // ---- synchronization --------------- // // THE SERVER ORDERS THE IMAGE BETWEEN ITS SESSIONS, the way a kernel's implicit sync would: // a writer publishes the fence of its write and moves on; a reader that finds the generation diff --git a/MobileGL/MG_Remote/Server/SharedImageYuv.h b/MobileGL/MG_Remote/Server/SharedImageYuv.h index a3a5b331..8ea903b5 100644 --- a/MobileGL/MG_Remote/Server/SharedImageYuv.h +++ b/MobileGL/MG_Remote/Server/SharedImageYuv.h @@ -7,12 +7,12 @@ // End of Source File Header // YUV SHARED IMAGES: the pure parts - plane copies and the YCbCr -> RGB conversion an image's -// colour hints select - kept free of Android and of any backend so the host tests can check them. +// color hints select - kept free of Android and of any backend so the host tests can check them. // // A YUV image is sampled as RGBA: whoever binds it to a texture gets the image CONVERTED into the // texture's own RGBA8 storage at its first use in each of the reader's frames (the backends do // that on the GPU, from the image's AHardwareBuffer). The conversion is the one the EGLImage's -// EGL_EXT_image_dma_buf_import hints name - colour space, sample range and chroma siting - with +// EGL_EXT_image_dma_buf_import hints name - color space, sample range and chroma siting - with // that extension's defaults (ITU-R BT.601, narrow range, siting 0) where a hint is absent. #pragma once diff --git a/MobileGL/MG_Remote/Transport/Doorbell.cpp b/MobileGL/MG_Remote/Transport/Doorbell.cpp index b98235d5..8da57ef7 100644 --- a/MobileGL/MG_Remote/Transport/Doorbell.cpp +++ b/MobileGL/MG_Remote/Transport/Doorbell.cpp @@ -385,7 +385,7 @@ namespace MobileGL::MG_Remote::Transport { m_dead.store(true, std::memory_order_release); return false; } - // Readiness with no bit we requested or recognise: there is + // Readiness with no bit we requested or recognize: there is // nothing to consume and no way to make progress, so refuse to // poll this descriptor again. MGLOG_D("MG_Remote doorbell: fd %d ready with revents=0x%X", m_fd, static_cast(pfd.revents)); diff --git a/MobileGL/MG_Remote/Transport/Doorbell.h b/MobileGL/MG_Remote/Transport/Doorbell.h index a6a59efc..a3392198 100644 --- a/MobileGL/MG_Remote/Transport/Doorbell.h +++ b/MobileGL/MG_Remote/Transport/Doorbell.h @@ -63,7 +63,7 @@ namespace MobileGL::MG_Remote::Transport { extern std::atomic g_spinItersPerUs; // Measures, clamps, stores and returns. Two threads that race here both // store a legitimate reading and neither is wrong; there is nothing to - // serialise, so nothing does. + // serialize, so nothing does. std::uint32_t CalibrateSpinItersPerUs(); } // namespace Detail diff --git a/MobileGL/MG_Remote/Transport/ILink.h b/MobileGL/MG_Remote/Transport/ILink.h index 1644db24..c8e59c41 100644 --- a/MobileGL/MG_Remote/Transport/ILink.h +++ b/MobileGL/MG_Remote/Transport/ILink.h @@ -91,7 +91,7 @@ namespace MobileGL::MG_Remote::Transport { // shared SEG_STAGE mapping; on StreamLink it indexes the trailing staged // region of the batch that carried the record. MGPBlobRef's spelling and // every honesty check over it (R-2) are unchanged either way - which is the - // property that lets the whole record catalogue cross a boundary with no + // property that lets the whole record catalog cross a boundary with no // mapping without a single record layout changing. struct LinkSpan { std::uint64_t Offset = 0; @@ -213,14 +213,14 @@ namespace MobileGL::MG_Remote::Transport { // P12: DECLARE THAT THIS SEQ'S ANSWER WILL BE READ, so that a link which can retain it // does. Called by the producer side of the wire, in seq order, BEFORE the record is // published - the answer cannot arrive before that, and the reader stores under the same - // mutex the declaration takes, so the hand-off needs no second synchronisation. + // mutex the declaration takes, so the hand-off needs no second synchronization. // // WHY THE DECLARATION AND NOT "RETAIN EVERYTHING": a server that ignores the no-reply bit // answers ~55,903 records in one frame where this client reads ~4,501, so retain-on-arrival // grows ~11.3 entries per create and any cap is reached in C/11.3 creates - after which the // eviction wave lands on precisely the oldest WANTED answer, which is the wedge this exists // to avoid. Keyed on the declaration, the retained set is bounded by the CLIENT's own - // deferral depth instead of by the server's behaviour. + // deferral depth instead of by the server's behavior. // // A link with RetainsReplies false ignores it (the default), and its callers must not // defer: see the capability's own note. diff --git a/MobileGL/MG_Remote/Transport/ITransport.h b/MobileGL/MG_Remote/Transport/ITransport.h index f608d7c6..e70fc142 100644 --- a/MobileGL/MG_Remote/Transport/ITransport.h +++ b/MobileGL/MG_Remote/Transport/ITransport.h @@ -75,7 +75,7 @@ namespace MobileGL::MG_Remote::Transport { // Receives one fd previously shared by the peer. On success *outFd owns // a descriptor this process must close. `sideband` receives the bytes - // that travelled with it (may be empty) and must be at least + // that traveled with it (may be empty) and must be at least // FdPassing::kMaxSidebandBytes: an fd offer is one datagram and cannot // be half-consumed, so the capacity is checked BEFORE anything is read // and a short buffer returns MOBILEGL_ERR_BUFFER_TOO_SMALL with the diff --git a/MobileGL/MG_Remote/Transport/InProcessTransport.cpp b/MobileGL/MG_Remote/Transport/InProcessTransport.cpp index 5ddcda6f..f49ecbf2 100644 --- a/MobileGL/MG_Remote/Transport/InProcessTransport.cpp +++ b/MobileGL/MG_Remote/Transport/InProcessTransport.cpp @@ -40,7 +40,7 @@ namespace MobileGL::MG_Remote::Transport { public: struct Direction { std::mutex mutex; - // One variable per predicate. A single cv signalled with + // One variable per predicate. A single cv signaled with // notify_one would let a SendFrame's wakeup land on a thread // blocked in ReceiveFd, which re-tests its own predicate and goes // straight back to sleep - leaving a queued message undelivered diff --git a/MobileGL/MG_Remote/Transport/LogForward.cpp b/MobileGL/MG_Remote/Transport/LogForward.cpp index 0dfa80ff..24a1d54c 100644 --- a/MobileGL/MG_Remote/Transport/LogForward.cpp +++ b/MobileGL/MG_Remote/Transport/LogForward.cpp @@ -229,7 +229,7 @@ namespace MobileGL::MG_Remote::Transport { ++m_counters.abandoned; return; } - // A gap before the acknowledgement is marked before it: the client reads the file after the + // A gap before the acknowledgment is marked before it: the client reads the file after the // ack arrives, and a gap it cannot see there is a gap it will read as "nothing was said". QueueGapNoticesLocked(/*lossyGapToo=*/true); Item item; diff --git a/MobileGL/MG_Remote/Transport/LogForward.h b/MobileGL/MG_Remote/Transport/LogForward.h index 98dbc754..230646db 100644 --- a/MobileGL/MG_Remote/Transport/LogForward.h +++ b/MobileGL/MG_Remote/Transport/LogForward.h @@ -88,7 +88,7 @@ namespace MobileGL::MG_Remote::Transport { // One line, `level` a MOBILEGL_LOG_LEVEL_* value. Never blocks on the peer below FATAL. void Offer(int level, const char* line); // A whole CtrlEnvelope frame, written after every line offered before it and never dropped - // or paced (the LogFlush acknowledgement). + // or paced (the LogFlush acknowledgment). void OfferControlFrame(std::vector frame); // Stops taking lines, drains within closeDrainMs, stops the sender. Idempotent; returns the // final counters. diff --git a/MobileGL/MG_Remote/Transport/ReplySlot.h b/MobileGL/MG_Remote/Transport/ReplySlot.h index e3d9ddbd..35535483 100644 --- a/MobileGL/MG_Remote/Transport/ReplySlot.h +++ b/MobileGL/MG_Remote/Transport/ReplySlot.h @@ -11,7 +11,7 @@ // server stamps the seq into the 16-byte ReplySlotHeader so a wrong-slot read is detected. // DECLINED is a real answer, not a failure: MapPersistent's nullptr, the Bool appliers' `false`. // A reply never exceeds one slot and is never chunked; the client bands large reads -// (ARCHITECTURE.md §13.1.3), so Post's refusal is a last line of defence. The server posts, then +// (ARCHITECTURE.md §13.1.3), so Post's refusal is a last line of defense. The server posts, then // advances appliedSeq (release); the client reads a slot only after an acquire load shows // appliedSeq >= seq. The fences in Post and Read cover readers that bypass appliedSeq. @@ -129,7 +129,7 @@ namespace MobileGL::MG_Remote::Transport { // Fatal{ReplyTooLarge, "ReadPixels x > "} // and abort. Never truncated, never chunked, and never a server-side // abort the client cannot name: Post's own refusal below stays as the - // last line of defence, but it fires on the apply thread with the record + // last line of defense, but it fires on the apply thread with the record // already on the wire, where the only thing the client sees is a hang. // // `format`/`type` are the GL enums the record carries (MGPReadbackInfo:: @@ -181,7 +181,7 @@ namespace MobileGL::MG_Remote::Transport { "record\" and can never name a slot (R-3: seq is 1-based)"); } if (size > MaxReplyBytes()) { - // The server's LAST line of defence, not the first: the client refuses an + // The server's LAST line of defense, not the first: the client refuses an // oversize ReadPixels by name before it emits (RequireReadPixelsFits, ID-47), // so reaching this means the two sides disagree about the frame. WireLogFatal("MG_Remote reply pool: Fatal{ProtocolCorruption} - a %llu byte answer " diff --git a/MobileGL/MG_Remote/Transport/Ring.cpp b/MobileGL/MG_Remote/Transport/Ring.cpp index dbc936be..cedbe14c 100644 --- a/MobileGL/MG_Remote/Transport/Ring.cpp +++ b/MobileGL/MG_Remote/Transport/Ring.cpp @@ -129,7 +129,7 @@ namespace MobileGL::MG_Remote::Transport { const std::uint64_t total = Align8(sizeof(RingRecordHeader) + payloadBytes); if (total > MaxRecordBytes()) { // A single record larger than HALF the ring is a caller bug: the - // record catalogue has to chunk oversized payloads (large subdata + // record catalog has to chunk oversized payloads (large subdata // becomes several records) rather than emit one giant record. // // Half, not the whole ring, because a record has to be placeable at @@ -260,7 +260,7 @@ namespace MobileGL::MG_Remote::Transport { // skipped HERE, silently, with the record lost and nothing logged on // either side. A genuine filler is always kind kRingPadRecordKind - // Reserve writes it two dozen lines above - and a call record always - // carries a real opcode, because the catalogue starts at 1. Requiring + // carries a real opcode, because the catalog starts at 1. Requiring // the pair costs one comparison and turns that collision from a lost // record into a record the decoder gets and can reject by name. if ((header.flags & kRecPad) != 0 && header.kind == kRingPadRecordKind) { @@ -271,7 +271,7 @@ namespace MobileGL::MG_Remote::Transport { out.kind = header.kind; out.flags = header.flags; out.payload = m_base + offset + sizeof(RingRecordHeader); - // Includes the alignment tail; the record catalogue knows the real + // Includes the alignment tail; the record catalog knows the real // payload length. out.payloadSize = size - sizeof(RingRecordHeader); out.cursor = m_localTail; diff --git a/MobileGL/MG_Remote/Transport/Ring.h b/MobileGL/MG_Remote/Transport/Ring.h index 08048d69..2ae210f7 100644 --- a/MobileGL/MG_Remote/Transport/Ring.h +++ b/MobileGL/MG_Remote/Transport/Ring.h @@ -159,7 +159,7 @@ namespace MobileGL::MG_Remote::Transport { "the doorbell flags are shared across processes: they must be lock-free"); // Per-record header. Prefix-identical to the plan's RecHeader so the - // generated record catalogue drops straight in. + // generated record catalog drops straight in. struct RingRecordHeader { std::uint16_t kind; std::uint16_t flags; @@ -193,7 +193,7 @@ namespace MobileGL::MG_Remote::Transport { kRecNoReply = 1u << 5, }; - // Reserved kind for the wrap filler. The catalogue starts at 1. + // Reserved kind for the wrap filler. The catalog starts at 1. inline constexpr std::uint16_t kRingPadRecordKind = 0; inline constexpr std::uint64_t kRingRecordAlignment = 8; diff --git a/MobileGL/MG_Remote/Transport/SessionRings.h b/MobileGL/MG_Remote/Transport/SessionRings.h index 01e77160..7e1ac19b 100644 --- a/MobileGL/MG_Remote/Transport/SessionRings.h +++ b/MobileGL/MG_Remote/Transport/SessionRings.h @@ -89,14 +89,14 @@ namespace MobileGL::MG_Remote::Transport { SessionSegments(const SessionSegments&) = delete; SessionSegments& operator=(const SessionSegments&) = delete; - // Creates and maps all four, initialises BOTH control pages (SEG_CMD's + // Creates and maps all four, initializes BOTH control pages (SEG_CMD's // and SEG_EVENT's), and books the mapping in `role`'s ledger. MobileGLResult Create(const SessionSegmentSizes& sizes, MemoryRole role); // Private, identically addressed mirrors for the stream data plane. MobileGLResult CreatePrivate(const SessionSegmentSizes& sizes, MemoryRole role); // The inproc peer's view of the owner's four segments, booked under the other role. It - // does not re-initialise the control pages: they are shared, and that would zero the + // does not re-initialize the control pages: they are shared, and that would zero the // owner's cursors. On POSIX each descriptor is dup()ed and adopted (ShmSegment::Adopt + // Map), a real second mapping, so the inproc attach runs the same path as the cross-process // one (AdoptFromDescriptors) and the two views close independently. Windows has no Adopt @@ -493,7 +493,7 @@ namespace MobileGL::MG_Remote::Transport { // ----------------------------------------------------------------------- // P6.5 wire fingerprint: one mixer, driven by compiler-derived layout facts. - // CapsCodec supplies generated member/catalogue digests; build identity and + // CapsCodec supplies generated member/catalog digests; build identity and // negotiated window sizes do not participate in wire compatibility. // ----------------------------------------------------------------------- // Wire facts only. Segment geometry and build identity are negotiated separately. diff --git a/MobileGL/MG_Remote/Transport/ShmSegment.cpp b/MobileGL/MG_Remote/Transport/ShmSegment.cpp index b93200bc..22d7db83 100644 --- a/MobileGL/MG_Remote/Transport/ShmSegment.cpp +++ b/MobileGL/MG_Remote/Transport/ShmSegment.cpp @@ -457,8 +457,8 @@ namespace MobileGL::MG_Remote::Transport { } } m_replySlotCount = replySlotCount; - // NOT DeriveViews' control-page initialisation: the SERVER created these - // and already initialised both RingControls. Re-initialising here would + // NOT DeriveViews' control-page initialization: the SERVER created these + // and already initialized both RingControls. Re-initializing here would // zero the owner's cursors out from under a session that is already // running - the same reason AttachInProcess does not do it either. DeriveViews(); diff --git a/MobileGL/MG_Remote/Transport/SocketTransport.h b/MobileGL/MG_Remote/Transport/SocketTransport.h index bd0a7d2c..83b20eea 100644 --- a/MobileGL/MG_Remote/Transport/SocketTransport.h +++ b/MobileGL/MG_Remote/Transport/SocketTransport.h @@ -160,7 +160,7 @@ namespace MobileGL::MG_Remote::Transport { bool m_tcp = false; TransportRole m_role = TransportRole::Client; - // ITransport's threading rule: callers serialise sends, and receives may + // ITransport's threading rule: callers serialize sends, and receives may // run on one dedicated reader thread concurrently with those sends. So // the two directions get one mutex each rather than one shared - a // single lock would make a blocked receive stall every send, which is diff --git a/MobileGL/MG_Remote/Wire/PipeWireCodec.cpp b/MobileGL/MG_Remote/Wire/PipeWireCodec.cpp index 9bea99ce..f8a08904 100644 --- a/MobileGL/MG_Remote/Wire/PipeWireCodec.cpp +++ b/MobileGL/MG_Remote/Wire/PipeWireCodec.cpp @@ -147,12 +147,12 @@ namespace MobileGL::MG_Remote::Wire { "MGPWireRecHeader::Size and RingRecordHeader::size are the same four bytes"); // --------------------------------------------------------------------------------- - // The catalogue, once. Name and payload type per opcode. + // The catalog, once. Name and payload type per opcode. // --------------------------------------------------------------------------------- // // ONE LIST, THREE READERS: the name table (Fatal lines), the payload-size table (the tail // arithmetic's base) and the decoder's own completeness assertion. Hand-maintained lists - // that say the same thing three times are how a catalogue edit lands in two of them. + // that say the same thing three times are how a catalog edit lands in two of them. // gen_pipe.py owns PipeCalls.def and PipeWire.inc; this list is held to them by the // kOpCount assertion under it, which is the strongest statement a non-generated file can // make about a generated enum. @@ -253,7 +253,7 @@ namespace MobileGL::MG_Remote::Wire { constexpr const char* kWireOpNames[] = {"", MGPW_FOR_EACH_CALL(MGPW_NAME_ROW)}; #undef MGPW_NAME_ROW - // The catalogue grew or shrank. Add the new opcode to MGPW_FOR_EACH_CALL, give it an + // The catalog grew or shrank. Add the new opcode to MGPW_FOR_EACH_CALL, give it an // arm in ApplyChecked, and decide in CONTRACT-P5.md table 1 whether it carries bytes. static_assert(sizeof(kWireOpNames) / sizeof(kWireOpNames[0]) == static_cast(MGPWireOp::kOpCount), "PipeCalls.def and this file's call list disagree"); @@ -783,7 +783,7 @@ namespace MobileGL::MG_Remote::Wire { break; } case MGPWireOp::BufferSubDataResident: { - // NO TAIL, because its catalogue row has no kVarTail (PipeCalls.def gives it + // NO TAIL, because its catalog row has no kVarTail (PipeCalls.def gives it // kHasBlob|kOptional) and MGPipeApplyBufferSubDataResident takes no regions. The // layout used to share ResourceSubData's arm, which meant a record with // RegionCount = 2 was REQUIRED to carry 80 bytes the arm then dropped on the @@ -1416,7 +1416,7 @@ namespace MobileGL::MG_Remote::Wire { PipeWireDecoder::PipeWireDecoder(Transport::RingControl* control, SegmentTable* segments, ReplySink* replies) : m_valid(control != nullptr), m_segments(segments), m_replies(replies) { m_auditPoison = MG_Config::Ipc.Audit; - // Once, at construction, beside the resolver it is modelled on - not per record from + // Once, at construction, beside the resolver it is modeled on - not per record from // the apply thread. The thunk is inert without a decoder on the calling thread, so an // early install changes nothing for a monolith caller of MGPipeApplyWireRecord. InstallApplyHook(); @@ -1490,7 +1490,7 @@ namespace MobileGL::MG_Remote::Wire { if ((MGPipeCallFlagsFor(op) & static_cast(kReplySlot)) == 0) { SessionFail(MGFatalFamily::ProtocolCorruption, "MGPipe: Fatal{ProtocolCorruption, \"%s\"} the decoder tried to answer into " - "a reply slot for a call the catalogue gives no kReplySlot; s1 sizes " + "a reply slot for a call the catalog gives no kReplySlot; s1 sizes " "ReplyPool from MGPipeCallFlagsFor and reserved none", WireOpName(op)); } @@ -1927,7 +1927,7 @@ namespace MobileGL::MG_Remote::Wire { case MGPWireOp::CreateSamplerState: { const auto& desc = *static_cast(payload); // R-13.1 gave this call its kHasBlob. The serialization IS the memcpy - a POD - - // and borderColorForm must survive BYTE FOR BYTE, because all three colour + // and borderColorForm must survive BYTE FOR BYTE, because all three color // representations are always numerically populated and it is the only thing that // says which one the backend must use (MGPSamplerDesc in MGPipeTypes.h). if (!RequireDeclaredBlob(op, desc.Parameters, *m_segments)) return false; @@ -1961,10 +1961,10 @@ namespace MobileGL::MG_Remote::Wire { case MGPWireOp::CreateShaderState: { const auto& desc = *static_cast(payload); // ONE ARCHIVE, NOT SEVEN RUNS - w1's ruling, and the cheapest one available. - // EncodeProgramArtifacts already serialises SpirvArtifacts::generatedSpirv, i.e. + // EncodeProgramArtifacts already serializes SpirvArtifacts::generatedSpirv, i.e. // every stage module, so Reflection names the WHOLE archive and Spirv[0..5] stay // undeclared. Shipping the modules a second time would double the largest record - // in the catalogue for no reader at all: MGPipeApplyCreateShaderState takes + // in the catalog for no reader at all: MGPipeApplyCreateShaderState takes // (desc, link*, spirv*) and reads the modules out of spirv->generatedSpirv - // PipeApply.cpp touches neither desc.Spirv[] nor desc.Reflection. // @@ -2090,7 +2090,7 @@ namespace MobileGL::MG_Remote::Wire { std::memcpy(&span, reinterpret_cast(spans) + i * sizeof(MGHostSpan), sizeof(MGHostSpan)); // ALL FOUR ARMS, the segment-range one included: this row and DrawVbo are - // the only two host-span carriers in the catalogue, and an out-of-segment + // the only two host-span carriers in the catalog, and an out-of-segment // span used to pass every check here. if (!CheckHostSpanIsHonest(span, *m_segments)) return false; } @@ -2277,7 +2277,7 @@ namespace MobileGL::MG_Remote::Wire { // drives rewrites its range from the AUTHORITATIVE SHADOW, which rule C makes // server-owned, so resource_subdata is already the only way bytes reach it and a // second way would be a forgeable one. AccessFlags cross verbatim, never - // normalised (MGPipeApplyResourceFlushRange in PipeApply.h). + // normalized (MGPipeApplyResourceFlushRange in PipeApply.h). MGPipeApplyResourceFlushRange(*static_cast(payload), nullptr); return true; diff --git a/MobileGL/MG_Remote/Wire/PipeWireCodec.h b/MobileGL/MG_Remote/Wire/PipeWireCodec.h index 20b328cf..36825eba 100644 --- a/MobileGL/MG_Remote/Wire/PipeWireCodec.h +++ b/MobileGL/MG_Remote/Wire/PipeWireCodec.h @@ -173,13 +173,13 @@ namespace MobileGL::MG_Remote::Wire { // `payload` must already be known to hold at least the op's payload struct - that is what // MGP_WIRE_CHECK_BOUNDS proves, and this function is only ever called after it. Returns - // false for an opcode outside the catalogue; a count past its own GL bound is Fatal, + // false for an opcode outside the catalog; a count past its own GL bound is Fatal, // because a decoder holding such a record has nothing safe left to do with it - and in an // armed session child (PH-1 (3)) that Fatal latches instead and this returns false too, which // is why the decoder asks the opcode question itself before calling. Bool MGPipeWireRecordLayout(MG_Pipe::MGPWireOp op, const void* payload, WireRecordLayout& out); - // The catalogue's own spelling of an opcode, for a Fatal line. Out of range is "". + // The catalog's own spelling of an opcode, for a Fatal line. Out of range is "". const char* WireOpName(MG_Pipe::MGPWireOp op); // P13 W5: the tail is MG_Pipe's (PipeVerbSink.h) - the record arm's in-process port speaks it too. @@ -437,7 +437,7 @@ namespace MobileGL::MG_Remote::Wire { // // RingControl::appliedSeq has exactly ONE writer - s1's SessionConsumer::ApplyOne, +1 // per record, pads never counted - and this class writes NO RingControl field at all. - // That is deliberate rather than a division of labour: two writers of a watermark is + // That is deliberate rather than a division of labor: two writers of a watermark is // how a waiter resumes on a record the server has not run, which is what R-9's "never // publish a watermark early" forbids, and there is no checksum on this ring that would // catch it. @@ -466,7 +466,7 @@ namespace MobileGL::MG_Remote::Wire { // WHAT IT ACTUALLY COVERS is "the blob runs the arm resolved", which today is AT MOST // ONE per record: tails live in SEG_CMD and are never noted, and CreateShaderState's // six per-stage runs are Fatal rather than resolved, so the one archive is the only - // multi-kilobyte run in the catalogue that reaches it. The array is eight deep so a + // multi-kilobyte run in the catalog that reaches it. The array is eight deep so a // later phase that declares more can fill it without a code change - and overflowing // it is Fatal rather than a silent drop, because a poison that quietly stopped // covering a run is the same failure as no poison at all. @@ -500,7 +500,7 @@ namespace MobileGL::MG_Remote::Wire { Uint64 SkippedAnswers() const; // Points MG_Pipe::gMGPipeWireRecordApply at this layer's thunk. Called once from the - // constructor and modelled on SegmentTable::InstallProcessResolver, which is the same + // constructor and modeled on SegmentTable::InstallProcessResolver, which is the same // shape for the same reason; Uninstall belongs beside that one at teardown. The thunk // is inert without a decoder on the calling thread, so installing it early changes // nothing for a monolith caller of MGPipeApplyWireRecord. diff --git a/MobileGL/MG_State/EGLState/Core.h b/MobileGL/MG_State/EGLState/Core.h index ff0f8200..3fcac5d6 100644 --- a/MobileGL/MG_State/EGLState/Core.h +++ b/MobileGL/MG_State/EGLState/Core.h @@ -200,7 +200,7 @@ namespace MobileGL { EGLint Pitch = 0; Bool HasModifier = false; Uint64 Modifier = 0; - // YUV (two planes): the second plane, and the colour hints (0 = not given). + // YUV (two planes): the second plane, and the color hints (0 = not given). Uint32 PlaneCount = 1; int Plane1Fd = -1; EGLint Plane1Offset = 0; diff --git a/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp b/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp index ae4e631c..c8eefdad 100644 --- a/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp +++ b/MobileGL/MG_State/GLState/BufferState/BufferObject.cpp @@ -118,7 +118,7 @@ namespace MobileGL::MG_State::GLState { const std::lock_guard lock(g_persistentReadMapsMutex); g_livePersistentReadMaps.erase(m_lifetimeId); } - // P3a D-L: the buffer's death crosses as resource_destroy, which is the catalogue + // P3a D-L: the buffer's death crosses as resource_destroy, which is the catalog // call for it - no seventh NotifyStateObjectDestroyed raiser is added, because that // header exists for kinds that have no such call. The emit-then-free ORDER is fixed // inside the helper and is not negotiable. @@ -322,7 +322,7 @@ namespace MobileGL::MG_State::GLState { // skipped for a resident store; residency now also comes from a // shader storage binding (EnsureGpuResidentStorage at draw time) and // from large-store adoption (TryAdoptLargeStorage), both of which an - // application then re-initialises through an ordinary map/write/unmap. + // application then re-initializes through an ordinary map/write/unmap. // Skipping the copy-back dropped every one of those writes. Land the // staged bytes through the same route glBufferSubData takes into an // adopted store - the backend's flush op is for stores it keeps a diff --git a/MobileGL/MG_State/GLState/BufferState/BufferObject.h b/MobileGL/MG_State/GLState/BufferState/BufferObject.h index d32e7e51..e5284cb8 100644 --- a/MobileGL/MG_State/GLState/BufferState/BufferObject.h +++ b/MobileGL/MG_State/GLState/BufferState/BufferObject.h @@ -147,7 +147,7 @@ namespace MobileGL { // Everything here is behind the build option AND behind // `MG_Config::Transport != Monolith` at the call site, because an extra // resource_subdata record or an extra respecify on the monolith path is new - // behaviour and D-J forbids it. The pull build compiles none of it, which is also + // behavior and D-J forbids it. The pull build compiles none of it, which is also // how G1 holds over a file this central. // ONE BLOCK of the mapped span (PersistentMapTracker::BlockBytes), emitted through diff --git a/MobileGL/MG_State/GLState/BufferState/BufferState.h b/MobileGL/MG_State/GLState/BufferState/BufferState.h index ab750fff..c4ca4f0d 100644 --- a/MobileGL/MG_State/GLState/BufferState/BufferState.h +++ b/MobileGL/MG_State/GLState/BufferState/BufferState.h @@ -95,7 +95,7 @@ namespace MobileGL::MG_State::GLState { // have moved" in one read, which is what a per-draw shutter can afford. // // #if MOBILEGL_PIPE_PUSH so the pull build's BufferState does not resize (G1) - the same - // licence TextureState::NoteImageUnitTouched took at P5d r3. + // license TextureState::NoteImageUnitTouched took at P5d r3. void NoteBindPointChanged(const BufferTarget target) { auto it = std::find(BufferBindPointTargets.begin(), BufferBindPointTargets.end(), target); if (it == BufferBindPointTargets.end()) return; diff --git a/MobileGL/MG_State/GLState/BufferState/PersistentMapTracker.cpp b/MobileGL/MG_State/GLState/BufferState/PersistentMapTracker.cpp index 2281c44e..63b08189 100644 --- a/MobileGL/MG_State/GLState/BufferState/PersistentMapTracker.cpp +++ b/MobileGL/MG_State/GLState/BufferState/PersistentMapTracker.cpp @@ -154,12 +154,12 @@ namespace MobileGL::MG_Record { // has no top-byte tag, which is why every host lane stayed green while all three // heavy-persistent-map traces died on the phone (device window #1, E0a/E1/E4a/E4b). // - // So the table stores NORMALISED addresses and the handler normalises si_addr before + // So the table stores NORMALIZED addresses and the handler normalizes si_addr before // it compares: one space, fixed at the two doors into this file. Protecting through a - // normalised base is exactly what protecting through the tagged one did - mprotect + // normalized base is exactly what protecting through the tagged one did - mprotect // untags its own address argument (do_mprotect_pkey's untagged_addr) - and every // other use of base/end here is either an mprotect or a difference against a shadow - // base normalised the same way, so nothing else has to change. Pointer DEREFERENCES + // base normalized the same way, so nothing else has to change. Pointer DEREFERENCES // keep the tagged pointer they came from (PushBlocksFor's two edge hashes), because // under a future MTE tagging level the tag is load-bearing for the access itself. // THE MASK IS NOT GUARDED BY THE ARCHITECTURE, deliberately, and that is what makes @@ -400,7 +400,7 @@ namespace MobileGL::MG_Record { // A SEGV_ACCERR this handler does not own. Legitimate (the JVM's implicit // null checks land here every time), so it is recorded and chained, never // refused - but recorded, because the ONE case where it is not legitimate - // is a page this module protected and then failed to recognise, and that + // is a page this module protected and then failed to recognize, and that // case is otherwise a tombstone with no mention of the tracker at all. g_declinedFaults.fetch_add(1, std::memory_order_relaxed); g_declinedFaultAddress.store(address, std::memory_order_relaxed); @@ -415,7 +415,7 @@ namespace MobileGL::MG_Record { // above all "a protected page holds only this shadow's bytes" - is made at // kPageBytes granularity, and mprotect protects at the KERNEL's. On a 16 KB-page // kernel (Android 15 admits them) a kPageBytes mprotect would silently cover - // three neighbouring 4 KB quarters that may be foreign memory, which is exactly + // three neighboring 4 KB quarters that may be foreign memory, which is exactly // the process-killer the page-granular shadow exists to keep out. So on such a // kernel the arm is not installed at all and every persistent write map takes // the hash arm: slower, never unsafe. Said once, not per map - and decided BEFORE @@ -509,11 +509,11 @@ namespace MobileGL::MG_Record { // arm, where as an "untracked" member it would veto the epoch skip for every // tracked buffer in the process (measured on device); end is clamped up to // base so the [base, end) arithmetic never underflows. - // NORMALISED AT THE DOOR (UntagAddress): everything this function publishes is + // NORMALIZED AT THE DOOR (UntagAddress): everything this function publishes is // compared against si_addr one day, and si_addr is the kernel's untagged // address. Nothing below may reconstruct a pointer from these - the only // consumers are mprotect, which untags its own argument, and differences - // against a shadow base PushBlocksFor normalises the same way. + // against a shadow base PushBlocksFor normalizes the same way. const uintptr_t shadowBase = UntagAddress(reinterpret_cast(shadow)); const uintptr_t rawBegin = shadowBase + rangeBegin; const uintptr_t rawEnd = shadowBase + rangeEnd; @@ -532,7 +532,7 @@ namespace MobileGL::MG_Record { if (end > shadowBase + shadowExtent) end = shadowBase + shadowExtent; // WIDENING NEVER DEMOTES A MAP THE INWARD ARM COULD HOLD. Outward covers up // to one page more than inward does for the same range (both ends rounded - // away instead of towards), so a map sitting on the bitmap's capacity that + // away instead of toward), so a map sitting on the bitmap's capacity that // was tracked inward before this round would otherwise fall off the tracker // altogether - onto the hash arm, where as an untracked member it vetoes the // epoch skip for every buffer in the process. It keeps the inward arm and @@ -626,7 +626,7 @@ namespace MobileGL::MG_Record { // once" would then be true only of the read-only verbs' whole push. g_faultEpoch.fetch_add(1, std::memory_order_release); // NAME THE FIRST MAPPING, ONCE PER PROCESS. This module's whole failure mode - // is silent - a range it protected, a fault it did not recognise, a tombstone + // is silent - a range it protected, a fault it did not recognize, a tombstone // that names the application's memcpy - and the device run that found it had // no line anywhere saying a mapping had even been registered, let alone at // what address, in whose allocation, or with which top byte. One line at the @@ -927,7 +927,7 @@ namespace MobileGL::MG_Record { if (tracked != nullptr) { const uintptr_t trackedBase = tracked->base.load(std::memory_order_acquire); const uintptr_t trackedEnd = tracked->end.load(std::memory_order_acquire); - // THE SAME NORMALISATION TrackWriteMap PUBLISHED WITH (UntagAddress), because + // THE SAME NORMALIZATION TrackWriteMap PUBLISHED WITH (UntagAddress), because // every use of shadowBase below is a DIFFERENCE against trackedBase and the two // must live in one address space. The bytes are read through `shadowBytes`, the // tagged pointer as the allocator handed it out, and never by rebuilding a diff --git a/MobileGL/MG_State/GLState/BufferState/PersistentMapTracker.h b/MobileGL/MG_State/GLState/BufferState/PersistentMapTracker.h index 266e6169..2758c950 100644 --- a/MobileGL/MG_State/GLState/BufferState/PersistentMapTracker.h +++ b/MobileGL/MG_State/GLState/BufferState/PersistentMapTracker.h @@ -101,7 +101,7 @@ namespace MobileGL::MG_Record { // The push's block size (THE GRANULARITY above). static constexpr Uint64 BlockBytes() { return 64ull * 1024ull; } // Transport != Monolith. The whole module is inert on the monolith path: an extra - // resource_subdata record there would be new behaviour, which D-J forbids. + // resource_subdata record there would be new behavior, which D-J forbids. static Bool PushIsArmed(); // r1 (P5-close codex finding 1, ID-52): true on the SERVER role's thread - the apply thread @@ -175,8 +175,8 @@ namespace MobileGL::MG_Record { static Uint64 FaultEpochForTest(); // Unit tests only, and the ONE row that carries the arm64 tagged-pointer defect: the // kernel reports si_addr untagged while every base this table publishes comes from a - // bionic-tagged heap pointer, so the ownership test has to normalise both sides. - // UntagAddressForTest is that normalisation and OwnershipProbeForTest is the row + // bionic-tagged heap pointer, so the ownership test has to normalize both sides. + // UntagAddressForTest is that normalization and OwnershipProbeForTest is the row // itself, run against a slot the caller composes rather than a live one. Both are // architecture-independent on purpose - the mask is the identity for every valid // userspace address off arm64 - so a host CI lane can drive them with the device's diff --git a/MobileGL/MG_State/GLState/BufferState/PipeResource.h b/MobileGL/MG_State/GLState/BufferState/PipeResource.h index f2a53fa9..bd72a7da 100644 --- a/MobileGL/MG_State/GLState/BufferState/PipeResource.h +++ b/MobileGL/MG_State/GLState/BufferState/PipeResource.h @@ -31,7 +31,7 @@ namespace MobileGL::MG_State::GLState { // page-aligned shadow (page-granular in SIZE as well, in a split build - see // ShadowAllocationBytesFor) owns every byte of every page it occupies, which is what // lets the persistent-map mprotect tracker write-protect the mapped range's containing - // pages without ever covering a neighbour allocation's byte (a foreign thread with + // pages without ever covering a neighbor allocation's byte (a foreign thread with // signals blocked faulting on a shared page is a process kill). // GL_MIN_MAP_BUFFER_ALIGNMENT keeps answering 64 - over-aligning an allocation is // invisible to the application, and a glMapBufferRange base that is page-aligned is diff --git a/MobileGL/MG_State/GLState/Core.cpp b/MobileGL/MG_State/GLState/Core.cpp index 7621d535..f117d205 100644 --- a/MobileGL/MG_State/GLState/Core.cpp +++ b/MobileGL/MG_State/GLState/Core.cpp @@ -594,7 +594,7 @@ namespace MobileGL::MG_State { continue; } // Stop at the end of EITHER side's array rather than walking onto the - // neighbouring uniform of whichever program has the shorter one. + // neighboring uniform of whichever program has the shorter one. if (!source.UniformLocationsAliasSameUniform(sourceBase, sourceLocation) || !destination.UniformLocationsAliasSameUniform(destinationBase, destinationLocation)) { break; @@ -616,7 +616,7 @@ namespace MobileGL::MG_State { const Uint sourceOffset = source.GetUniformOffset(sourceLocation); const Uint destinationOffset = destination.GetUniformOffset(destinationLocation); // Either side can legitimately lack backing storage: the optimizer deletes a - // uniform nothing reads, and a program whose SPIR-V phase settled cancelled + // uniform nothing reads, and a program whose SPIR-V phase settled canceled // has no shadow at all. Both report kInvalidUniformOffset / a null shadow. if (sourceUbo == nullptr || destinationUbo == nullptr || sourceOffset == ProgramObject::kInvalidUniformOffset || @@ -1402,7 +1402,7 @@ namespace MobileGL::MG_State { } Uint64 GLContext::AllocateTransformFeedbackLifetimeId() { - // Starts at 1 so a zero-initialised backend slot can never carry a live object's id. + // Starts at 1 so a zero-initialized backend slot can never carry a live object's id. static std::atomic nextId{1}; return nextId.fetch_add(1, std::memory_order_relaxed); } @@ -1420,7 +1420,7 @@ namespace MobileGL::MG_State { // A second context in the group makes the dirty walk read the share clocks. m_shareGroup->NoteContextAttached(); // The default transform feedback object (name 0) exists from the start of the context - // (GL 4.6 core 13.2.1), but nothing binds it, so nothing else would materialise it. + // (GL 4.6 core 13.2.1), but nothing binds it, so nothing else would materialize it. // Materialising it here is what lets GetBoundTransformFeedbackLifetimeId() be a plain // const read instead of an operator[] insert on the draw path. m_boundTransformFeedbackLifetimeId = m_transformFeedbackObjects[0].lifetimeId; diff --git a/MobileGL/MG_State/GLState/Core.h b/MobileGL/MG_State/GLState/Core.h index 3fdc785a..ee44f6c6 100644 --- a/MobileGL/MG_State/GLState/Core.h +++ b/MobileGL/MG_State/GLState/Core.h @@ -597,7 +597,7 @@ namespace MobileGL { // itself when it rehashes. The cache is refreshed by // RestoreBoundTransformFeedbackState, which every bind (and the revert a delete // performs) goes through, and seeded for the default object by the constructor. - // Never returns 0 - the counter starts at 1 so a zero-initialised memo slot cannot + // Never returns 0 - the counter starts at 1 so a zero-initialized memo slot cannot // be mistaken for a live object. Uint64 GetBoundTransformFeedbackLifetimeId() const { return m_boundTransformFeedbackLifetimeId; } Uint64 GetTransformFeedbackLifetimeId(Uint index) const; @@ -731,7 +731,7 @@ namespace MobileGL { Uint64 recordedVertices = 0; Bool hasCompletedSpan = false; Bool everBound = false; - // Assigned by the default member initialiser, so every way an object comes into + // Assigned by the default member initializer, so every way an object comes into // being - operator[] materialisation, `= {}` in Gen/Create - gets a fresh one, // and a recycled NAME never brings the dead object's id back with it. Uint64 lifetimeId = AllocateTransformFeedbackLifetimeId(); diff --git a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp index 0d2d8472..9fec8201 100644 --- a/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp +++ b/MobileGL/MG_State/GLState/FramebufferState/FramebufferObject.cpp @@ -27,7 +27,7 @@ namespace MobileGL::MG_State::GLState { // P4a D-I2: A FRAMEBUFFER HAS A HANDLE AND NO WIRE LIFETIME. PipeCalls.def carries // resource_destroy and five delete_* rows and NO framebuffer delete, because a // framebuffer is not a resource and is not a CSO - it is STATE, and - // set_framebuffer_state is the only call that names one - and the catalogue is closed, + // set_framebuffer_state is the only call that names one - and the catalog is closed, // so P4a invents no row. The helper is therefore steps 2 and 3 only: the death notice, // raised while the handle still resolves (this is the P2 step-e2 announcement that used // to stand here alone - the last SharedPtr to this object dropping, not the glDelete* diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramArtifacts.h b/MobileGL/MG_State/GLState/ProgramState/ProgramArtifacts.h index f015087a..fbbe1461 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramArtifacts.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramArtifacts.h @@ -97,7 +97,7 @@ namespace MobileGL::MG_State::GLState { // glslang's list, in TProgram index order, carrying uniform blocks, storage blocks and the // synthesized atomic-counter blocks together, one entry per ARRAY ELEMENT. DirectVulkan's // resource queries speak a different index space entirely - the one its SPIRV-Reflect walk - // produces: storage descriptors only, normalised block name with the array subscript + // produces: storage descriptors only, normalized block name with the array subscript // stripped, deduplicated across stages. `GetShaderStorageBlockIndex(name)` hands that index // out and `GetShaderStorageBlockBinding(index)` reads it back, so the two have to agree // with each other and with the names ProgramFactory::ReflectLayout looks up (which come @@ -119,7 +119,7 @@ namespace MobileGL::MG_State::GLState { // type too, and one more Vector member would change its size, its implicit destructor and // its move constructor in a build whose .text must stay byte-identical. struct StorageBlockReflection { - // The NORMALISED name: the SPIR-V block type name with a trailing array subscript + // The NORMALIZED name: the SPIR-V block type name with a trailing array subscript // stripped, which is what SpvReflectDescriptorBinding's type_name answers and what // ProgramFactory::ReflectLayout looks blocks up by. String name; @@ -415,7 +415,7 @@ namespace MobileGL::MG_State::GLState { // uniformOffsets, because the member has no GL location at all: the link task keeps // it out of the GL-visible uniform index space so no application can see or write it. Uint reservedNumSamplesOffset = kInvalidUniformOffset; - // False for a program whose SPIR-V was never produced (phase B cancelled at + // False for a program whose SPIR-V was never produced (phase B canceled at // teardown or by a relink) or whose optimizer run failed. GL has no way to // retract a LINK_STATUS it already reported true, so such a program stays // "linked" and every reflection answer it has given stays correct - it is simply diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramArtifactsCodec.h b/MobileGL/MG_State/GLState/ProgramState/ProgramArtifactsCodec.h index 45f48a1b..7e455ee8 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramArtifactsCodec.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramArtifactsCodec.h @@ -26,7 +26,7 @@ // "this record does not declare its blob" - and MGPipeApplyCreateShaderState takes the two // structs by pointer beside the record, so the applier reads the frontend's own archive and // this codec is never called. The VERIFY build is where it is exercised, and it is exercised -// as LIVE CODE WITH A GATE rather than as dead code with a unit test: the applier serialises, +// as LIVE CODE WITH A GATE rather than as dead code with a unit test: the applier serializes, // deserialises and field-compares before storing, and a mismatch is // Fatal{PipeVerifyDiffer, "program-archive"}. Under split, P5 is what makes it the transport's // path. diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramLinkTask.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramLinkTask.cpp index 73b6e3fc..a1d6c365 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramLinkTask.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramLinkTask.cpp @@ -108,7 +108,7 @@ namespace { // P7 OQ-8. ShaderStage -> EShLanguage, so a reflection record's `stages` mask (which is an // EShLanguageMask) can be tested against the stage of a snapshotted shader. Written here // rather than lifted into a shared header because this is the only caller and - // ProgramArtifacts.h's include-closure probe forbids this file's neighbours from growing a + // ProgramArtifacts.h's include-closure probe forbids this file's neighbors from growing a // dependency on ShaderStage.h. EShLangCount means "no glslang stage", which the caller // skips rather than guesses at. static EShLanguage ShaderStageToEShLanguage(MobileGL::ShaderStage stage) { @@ -191,7 +191,7 @@ namespace { // counters declared at the same binding AND the same offset therefore linked cleanly. // // The offsets themselves survive that lowering (reflection and the SPIR-V generator both - // honour layoutOffset), so the check belongs here, over the same model the GL queries answer + // honor layoutOffset), so the check belongs here, over the same model the GL queries answer // from. Returns the info-log line for an illegal layout, empty for a legal one. static MobileGL::String ValidateAtomicCounterLayout(glslang::TProgram& reflection) { using MobileGL::Bool; @@ -632,7 +632,7 @@ namespace { namespace MobileGL::MG_State::GLState { namespace { // The artifacts of a compile that ran to completion, or the never-compiled defaults. - // A node that was abandoned (cancelled at teardown, or whose body threw) published + // A node that was abandoned (canceled at teardown, or whose body threw) published // nothing, so it reads exactly like "never compiled" - which is the same collapse // ShaderObject's join gate performs, and is what keeps the link's view of a shader // identical whether it went through the object or through the snapshot. @@ -854,7 +854,7 @@ namespace MobileGL::MG_State::GLState { } } - // The last two are OUT parameters that mapIO fills, not requests it honours: the IO + // The last two are OUT parameters that mapIO fills, not requests it honors: the IO // mapper's collect callback is the last point at which a resource's qualifier still // says what the SHADER declared rather than what glslang assigned, so both captures // have to be taken from inside the link. See TMglGlslIoResolver::reserverResourceSlot. @@ -1066,7 +1066,7 @@ namespace MobileGL::MG_State::GLState { // three dumps are the same bytes (md5 39ffa10d5186a4d37be82d0b42297a8d). The order // does not perturb SPIR-V on this pin, including on the exact flow 0d052719 feared. // - // Not a licence to stop measuring: 0d052719's observation was real once, and the + // Not a license to stop measuring: 0d052719's observation was real once, and the // method (per-module hashes, both orders) is cheap. Re-run it on any glslang bump. // // So the order is now the other way round, and deliberately: reflection, fragment @@ -1547,7 +1547,7 @@ namespace MobileGL::MG_State::GLState { // "this opaque uniform has no location" as well. constexpr Uint kNoLocation = ~static_cast(0); // The ceiling glGetIntegerv(GL_MAX_UNIFORM_LOCATIONS) advertises, which is what the - // allocator below has to honour: locations 0..kMaxUniformLocations-1 and no others. + // allocator below has to honor: locations 0..kMaxUniformLocations-1 and no others. constexpr Uint kMaxUniformLocations = static_cast(ProgramObject::MAX_UNIFORM_LOCATIONS); Vector effectiveLocation(tProgramUniformCount, kNoLocation); Vector locationIsSourceExplicit(tProgramUniformCount, false); @@ -2043,7 +2043,7 @@ namespace MobileGL::MG_State::GLState { // // for each SPIR-V module, IN LINKED-STAGE ORDER // take its STORAGE_BUFFER descriptors - // sorted by (normalised block name, binding) + // sorted by (normalized block name, binding) // appending any name not already present // // Every clause is reproducible from what phase A already owns. `in.shaders` is the linked @@ -2051,7 +2051,7 @@ namespace MobileGL::MG_State::GLState { // the same order, that ProgramSpirvTask turns into `generatedSpirv` one module per entry - // so iterating it iterates the modules. `blockReflection[].stages` is an EShLanguageMask, // which is what says whether a given block is one of a given module's descriptors. The - // name normalisation is StripArrayElementSuffix, which is the same "[k]" strip + // name normalization is StripArrayElementSuffix, which is the same "[k]" strip // NormalizeDescriptorName does to the SPIR-V type name: glslang expands an INSTANCE ARRAY // into one reflection entry per element ("Foo[0]", "Foo[1]") while SPIR-V carries one // descriptor with a count, so stripping is what makes the two agree on ONE entry named @@ -2088,7 +2088,7 @@ namespace MobileGL::MG_State::GLState { if ((block.stages & stageBit) == 0) continue; ofThisStage.push_back(&block); } - // STABLE, so two entries that normalise to one name keep their declaration order + // STABLE, so two entries that normalize to one name keep their declaration order // and the FIRST (element 0, the base binding) is the one that survives the dedupe - // which is the element SPIRV-Reflect's single descriptor reports. std::stable_sort(ofThisStage.begin(), ofThisStage.end(), @@ -2230,7 +2230,7 @@ namespace MobileGL::MG_State::GLState { // every declared block of every stage BEFORE the write-back above happens - so "declared no // binding" is a fact read off the AST, not a guess made about the text. The lexical scanner // this replaced could only report positively, dropping any declaration whose grammar it did - // not fully recognise, and could not read `binding = SOME_MACRO` at all (it ran on + // not fully recognize, and could not read `binding = SOME_MACRO` at all (it ran on // macro-unexpanded source, and reading "no literal" as "no binding" once aliased eight // Flywheel storage blocks onto 0). // @@ -2266,7 +2266,7 @@ namespace MobileGL::MG_State::GLState { // them to the draw-buffer range fails the link of every such program. if (artifacts.program->getIntermediate(EShLangFragment) == nullptr) return true; - // Keyed on (colour number, COLOUR INDEX), not on the colour number alone. Two fragment + // Keyed on (color number, COLOR INDEX), not on the color number alone. Two fragment // outputs may share a location as long as their index differs - that pair IS dual-source // blending (GL 4.6 core 11.1.3 / ARB_blend_func_extended, core since 3.3), spelled either // `layout(location = 0, index = 0)` + `layout(location = 0, index = 1)` in the shader or @@ -2285,7 +2285,7 @@ namespace MobileGL::MG_State::GLState { const Int location = explicitLocation != in.explicitFragDataLocation.end() ? static_cast(explicitLocation->second) : static_cast(output.layoutLocation()); - // The colour INDEX, under the one precedence rule the whole codebase uses: a NON-ZERO + // The color INDEX, under the one precedence rule the whole codebase uses: a NON-ZERO // glBindFragDataLocationIndexed index wins, and a zero (or absent) one falls back to // the shader's own layout(index = N). // diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramLinkTask.h b/MobileGL/MG_State/GLState/ProgramState/ProgramLinkTask.h index c0607109..ad443b10 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramLinkTask.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramLinkTask.h @@ -67,7 +67,7 @@ namespace MobileGL::MG_State::GLState { Bool separable = false; // The four "takes effect at the next link" request maps. Snapshotted rather than // referenced, which is precisely what makes glBindAttribLocation and friends - // legal to call over a pending link without cancelling it: the pending link keeps + // legal to call over a pending link without canceling it: the pending link keeps // linking the inputs it was given. UnorderedMap explicitAttribLocations; // glBindAttribLocation UnorderedMap explicitFragDataLocation; // glBindFragDataLocation @@ -153,7 +153,7 @@ namespace MobileGL::MG_State::GLState { SharedPtr linkArtifactsForCache; // The one flag phase B tests before doing anything: false means this link never - // reached the tail of RunBody (it failed, or was cancelled mid-body). + // reached the tail of RunBody (it failed, or was canceled mid-body). Bool ready = false; } spirvHandoff; diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp index 69654354..21f96e7a 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.cpp @@ -126,7 +126,7 @@ namespace MobileGL::MG_State::GLState { // and describe a program that no longer exists. BumpLinkObservableVersions(); } - // A node that settled as Cancelled published nothing, and m_artifacts still holds + // A node that settled as Canceled published nothing, and m_artifacts still holds // what Link()'s prologue left there: cleared, LINK_STATUS false, no info log. That is // the correct answer for a link that was superseded or abandoned, and it is why no // caller of CancelLink() has to repair anything afterwards. @@ -160,7 +160,7 @@ namespace MobileGL::MG_State::GLState { if (pending->IsComplete()) { m_spirv = Move(pending->artifacts); } - // A node that settled as Cancelled published nothing, so m_spirv stays empty with + // A node that settled as Canceled published nothing, so m_spirv stays empty with // spirvStatus false: linked, queryable, not drawable. Nothing to repair. // Order matters, and it is the GL order. The shadow arrives zero-filled; the shaders' @@ -207,7 +207,7 @@ namespace MobileGL::MG_State::GLState { // MobileGL parses with Vulkan-relaxed rules, which sweep default-block uniforms into // MGL_GLOBAL_UBO; a block member cannot carry an initializer in SPIR-V, so glslang hands // the folded constants over as a side-channel (TIntermediate::getUniformInitializers) and - // this is where they are honoured. Without it every such uniform silently read zero - + // this is where they are honored. Without it every such uniform silently read zero - // which is what half of KHR-GL43.shader_storage_buffer_object was actually failing on. // // Writes go straight into the shadow rather than through glUniform*: this runs INSIDE the @@ -221,7 +221,7 @@ namespace MobileGL::MG_State::GLState { const auto& initializers = Artifacts().uniformInitialValues; if (initializers.empty()) return; if (m_spirv.globalUboScratch.empty() || m_spirv.uniformOffsets.empty()) { - // Phase B published no shadow (cancelled, or superseded by a relink). The program + // Phase B published no shadow (canceled, or superseded by a relink). The program // is not drawable; there is nowhere for these to land. return; } @@ -328,7 +328,7 @@ namespace MobileGL::MG_State::GLState { bytes.swap(m_pendingUniformBytes); if (m_spirv.globalUboScratch.empty() || m_spirv.uniformOffsets.empty()) { - // Phase B produced nothing (cancelled at teardown, or a relink superseded it). + // Phase B produced nothing (canceled at teardown, or a relink superseded it). // The program is not drawable, so there is nowhere for these to land and nothing // that could observe them. MGLOG_D("ProgramObject %u: dropping %zu buffered uniform write(s); the SPIR-V job published no shadow", @@ -362,8 +362,8 @@ namespace MobileGL::MG_State::GLState { } void ProgramObject::CancelLink() { - // Phase B first: it is chained behind phase A, so cancelling A would otherwise run A's - // continuation and post a node this call is about to abandon anyway. Cancelling it up + // Phase B first: it is chained behind phase A, so canceling A would otherwise run A's + // continuation and post a node this call is about to abandon anyway. Canceling it up // front makes that continuation a no-op. // // Cooperative and non-blocking, both of them. A node that no worker has picked up @@ -471,7 +471,7 @@ namespace MobileGL::MG_State::GLState { // NO CancelLink here, nor in DetachShader below. Both only edit the attach lists, which // a pending link does not read - it snapshotted (stage, source, compile node) per shader // at enqueue and is isolated from every later mutation. GL agrees: attaching or detaching - // takes effect at the NEXT link and leaves the current LINK_STATUS alone, so cancelling + // takes effect at the NEXT link and leaves the current LINK_STATUS alone, so canceling // would make `glLinkProgram; glAttachShader; glGetProgramiv(LINK_STATUS)` report FALSE // for a link that succeeded - and would break glCreateShaderProgramv outright, since that // is specified as link-then-detach and would discard its own link before anyone read it. @@ -631,7 +631,7 @@ namespace MobileGL::MG_State::GLState { // The capture stage is the LAST vertex-processing stage the program has, which is the same // rule ProgramLinkTask::ResolveTransformFeedbackVaryings resolves the names against. The // application's own request wins if it made one: that can only happen on a mixed program, - // which is not a shape ARB_gl_spirv defines, and honouring what the application explicitly + // which is not a shape ARB_gl_spirv defines, and honoring what the application explicitly // asked for is the safer of the two readings. if (task->in.requestedXfbVaryings.empty()) { for (const ShaderStage captureStage : diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h index c779019c..960fcb43 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramObject.h @@ -503,8 +503,8 @@ namespace MobileGL::MG_State::GLState { // PHASE B (joins the SPIR-V job; see EnsureSpirvJoined). // // BOUNDS-CHECKED, and that is not defensive padding - it is the load-bearing half of - // the "linked but not drawable" contract. A phase B that settles CANCELLED rather than - // Complete (its body threw, the pool failed to enqueue it, or teardown cancelled it + // the "linked but not drawable" contract. A phase B that settles CANCELED rather than + // Complete (its body threw, the pool failed to enqueue it, or teardown canceled it // while phase A had already published) publishes nothing, so the shadow is a // default-constructed SpirvArtifacts with an EMPTY uniformOffsets - while LINK_STATUS // stays GL_TRUE, because GL gives no way to retract one, and IsValidUniformLocation() @@ -735,7 +735,7 @@ namespace MobileGL::MG_State::GLState { } // PHASE B, all three (see EnsureSpirvJoined): the shadow buffer's layout is decided // by the OPTIMIZED SPIR-V, so it does not exist until the SPIR-V job has settled - and - // never exists at all for a program whose SPIR-V job settled cancelled. These three + // never exists at all for a program whose SPIR-V job settled canceled. These three // degrade to nullptr/nullptr/0 in that case, which is exactly the "no backing storage" // shape every caller already tests for (see GetUniformOffset's note). void* MapUBO() { return Spirv().globalUboScratch.data(); } @@ -780,7 +780,7 @@ namespace MobileGL::MG_State::GLState { Bool IsEsOrigin() const { return Artifacts().esOrigin; } // Publishes `samples` into the global-UBO shadow. Returns false when there is nowhere to - // put it - no shim in this program, no SPIR-V (a cancelled phase B), or the optimizer + // put it - no shim in this program, no SPIR-V (a canceled phase B), or the optimizer // dropped the member because nothing read it after all - all of which are ordinary states, // not errors. A value-identical write is dropped without bumping the content version, so a // steady stream of draws into one framebuffer does not force a re-upload per draw. @@ -870,10 +870,10 @@ namespace MobileGL::MG_State::GLState { ++m_backendStateVersion; // IMAGE units get their own generation, and it is not redundant with the one // above. A sampler unit is re-issued to the driver per draw as a plain - // glUniform1i, so a backend can honour a change without rebuilding anything; an + // glUniform1i, so a backend can honor a change without rebuilding anything; an // image unit cannot be, because ES forbids glUniform1i on image uniforms - Espryt // has to BAKE it into the ESSL it generates (RebindImageUniformsToFrontendUnits), - // which means the change is only honoured by regenerating the program. That + // which means the change is only honored by regenerating the program. That // regeneration is gated on link-shaped versions, so without a counter that moves // here the new unit would never reach the driver. if (GetUniformTypeFacts(location).isImage) { @@ -1110,7 +1110,7 @@ namespace MobileGL::MG_State::GLState { } // PHASE B (see EnsureSpirvJoined). Empty for a program whose SPIR-V job was - // cancelled; GetSpirvStatus() below is how a backend tells that apart from a program + // canceled; GetSpirvStatus() below is how a backend tells that apart from a program // that never linked. Vector>& GetGeneratedSpirv() { return Spirv().generatedSpirv; } const Vector>& GetGeneratedSpirv() const { return Spirv().generatedSpirv; } @@ -1228,7 +1228,7 @@ namespace MobileGL::MG_State::GLState { // glProgramParameteri) NOR by glAttachShader/glDetachShader. Every one of those is // defined by GL to leave the CURRENT link result alone, and the pending link already // snapshotted its own inputs at enqueue, so it is computing exactly the answer GL - // requires. Cancelling on any of them would make + // requires. Canceling on any of them would make // glLinkProgram(p); ; glGetProgramiv(p, GL_LINK_STATUS) // report FALSE for a link that succeeded - and for the attach/detach pair it would // additionally break glCreateShaderProgramv, which detaches immediately after linking. diff --git a/MobileGL/MG_State/GLState/ProgramState/ProgramSpirvTask.cpp b/MobileGL/MG_State/GLState/ProgramState/ProgramSpirvTask.cpp index e1b6a7ea..2dd344c2 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ProgramSpirvTask.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ProgramSpirvTask.cpp @@ -117,7 +117,7 @@ namespace MobileGL::MG_State::GLState { ProgramLinkTask::SpirvHandoff& handoff = m_phaseA->spirvHandoff; const Uint externalIndex = m_phaseA->in.externalIndex; if (!handoff.ready) { - // Phase A did not reach its tail (it failed the link, or was cancelled mid-body). + // Phase A did not reach its tail (it failed the link, or was canceled mid-body). // Publish nothing; spirvStatus stays false. return; } diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderCompileAdoptionMap.cpp b/MobileGL/MG_State/GLState/ProgramState/ShaderCompileAdoptionMap.cpp index 3fb575db..c82b2136 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderCompileAdoptionMap.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderCompileAdoptionMap.cpp @@ -23,11 +23,11 @@ namespace MobileGL::MG_State::GLState { if (it == m_entries.end()) return nullptr; SharedPtr node = it->second.lock(); - // Expired (every shader object that held it has released it), settled as Cancelled + // Expired (every shader object that held it has released it), settled as Canceled // (the enqueue lost a race with teardown, or the body threw), or CANCELLATION // REQUESTED but not yet settled (a releaser fired Cancel() while a worker was still // inside RunBody(), so the node is stuck at Running until the body returns - see - // JobNode::Run: once m_cancelled is set, the node is DOOMED to end up Cancelled no + // JobNode::Run: once m_cancelled is set, the node is DOOMED to end up Canceled no // matter how the body finishes, it just has not gotten there yet). All three can // never publish artifacts a caller may rely on, so all three are misses. Only the // first two are dead weight worth pruning from the index here - a cancellation- @@ -54,7 +54,7 @@ namespace MobileGL::MG_State::GLState { SweepIfCrowded(); // operator[] rather than a find/insert pair: an existing entry for this key is either - // a re-registration of the same source (the previous node expired or was cancelled) + // a re-registration of the same source (the previous node expired or was canceled) // or an astronomically rare hash collision. The newcomer wins in both cases. m_entries[ShaderSourceKey{.stage = node->stage, .sourceHash = node->sourceHash, diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderCompileAdoptionMap.h b/MobileGL/MG_State/GLState/ProgramState/ShaderCompileAdoptionMap.h index 682ae3e3..e2706c38 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderCompileAdoptionMap.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderCompileAdoptionMap.h @@ -44,7 +44,7 @@ namespace MobileGL::MG_State::GLState { // // ---- Lifetime and pruning ---- // WeakPtr, never SharedPtr: the map is an index, not an owner. An entry whose node has - // been released by every shader object simply expires, and a node that was CANCELLED + // been released by every shader object simply expires, and a node that was CANCELED // carries no result at all, so both are treated as misses and pruned where they are // found. Pruning is otherwise amortized: Register() sweeps the whole map whenever it has // grown past twice its size at the last sweep, which bounds the map at O(live nodes) @@ -60,10 +60,10 @@ namespace MobileGL::MG_State::GLState { // A hit is honored only after the FULL source text has been compared byte for byte // against the candidate node's own snapshot: the hash in the key is a lookup // accelerator, never the answer (ShaderSourceKey). A node that has settled as - // Cancelled is never handed out - it published nothing, so adopting it would give the + // Canceled is never handed out - it published nothing, so adopting it would give the // new object a compile that can never report anything but GL_FALSE. Nor is a node // whose cancellation has merely been REQUESTED but not yet settled (still Running, - // with IsCancellationRequested() true): JobNode::Run forces such a node to Cancelled + // with IsCancellationRequested() true): JobNode::Run forces such a node to Canceled // the moment its body returns regardless of how the body finished, so it is already // doomed and handing it out would just move the same GL_FALSE-with-no-log outcome to // a second, unrelated shader object. diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderCompileTask.cpp b/MobileGL/MG_State/GLState/ProgramState/ShaderCompileTask.cpp index eb8ace1a..bc1a5457 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderCompileTask.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderCompileTask.cpp @@ -239,7 +239,7 @@ namespace MobileGL::MG_State::GLState { // deferral mechanism (and JobNode's debug assert on it) exists. void ShaderCompileTask::RunBody() { // Own the failure rather than letting JobNode's backstop settle the node as - // Cancelled: an abandoned node publishes nothing, so the shader would report + // Canceled: an abandoned node publishes nothing, so the shader would report // COMPILE_STATUS false with an EMPTY info log. GL models a failed compile as // status + log, so turn a throw into exactly that - a completed job whose result // is "this shader did not compile", with a log the application can read. diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderCompileTask.h b/MobileGL/MG_State/GLState/ProgramState/ShaderCompileTask.h index 7115f285..8fc051c0 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderCompileTask.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderCompileTask.h @@ -179,7 +179,7 @@ namespace MobileGL::MG_State::GLState { // // Const because the claim is the node's own synchronization, not a mutation of its // published artifacts: a claim that is taken and then abandoned (its link was - // cancelled) costs one extra re-parse later and nothing else. + // canceled) costs one extra re-parse later and nothing else. SharedPtr ClaimParsedShader(String& outReparseLog) const; // Sticky marker for "a ProgramLinkTask has this node in its input snapshot". @@ -226,7 +226,7 @@ namespace MobileGL::MG_State::GLState { // // The CANCEL that the count authorizes still races the worker, and deliberately so - // that is the settled cancel-not-join semantics from stage 3: JobNode::Cancel is - // cooperative and non-blocking, a node already running settles as Cancelled when its + // cooperative and non-blocking, a node already running settles as Canceled when its // body returns, and a node that has already gone terminal ignores the request. // Nothing about that changes here. // diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp index 1617e802..4d8e2731 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.cpp @@ -90,7 +90,7 @@ namespace MobileGL::MG_State::GLState { // byte-identical one cannot change what a compile would produce: the whole // pipeline (preprocess -> lexical checks -> glslang parse) is a pure function of // (stage, source, CompileEnv). So keeping the compiled state is not an optimization - // that changes observable behaviour - the COMPILE_STATUS, the info log and the + // that changes observable behavior - the COMPILE_STATUS, the info log and the // reflection a caller can query are exactly what a real recompile would have // rebuilt, byte for byte. A compile still IN FLIGHT is left running for the same // reason: it is computing the right answer for text this object still holds. @@ -142,7 +142,7 @@ namespace MobileGL::MG_State::GLState { // GL-observable half of a failure, COMPILE_STATUS and the info log, lives in // `artifacts` and every sharer reads the identical copy of it. MG_Util::Async::ApplyDeferredDiagnostics(*m_compiled); - // A node that settled as Cancelled published nothing. Dropping it here is what keeps + // A node that settled as Canceled published nothing. Dropping it here is what keeps // the object's state machine to two reachable cases - "no job" and "a job that // completed" - so every reader below can treat a live node as authoritative. // @@ -196,7 +196,7 @@ namespace MobileGL::MG_State::GLState { // authorized to cancel only if BOTH say the result has become unobservable. // // 1. Other shader objects. From stage 6 a node can be SHARED by several GL shader - // names that were handed byte-identical source; cancelling here would turn a + // names that were handed byte-identical source; canceling here would turn a // compile they must still see as GL_TRUE into GL_FALSE. Only the releaser that // takes the count to zero - i.e. the last holder - may cancel. See // ShaderCompileTask::AddAdopter for why a plain Int is sound here and for the @@ -258,7 +258,7 @@ namespace MobileGL::MG_State::GLState { // Hoisted above the node construction because stage 6 keys off it too: this same // answer decides whether the adoption map is consulted at all, so a // glMaxShaderCompilerThreadsKHR(0) and a flag-off build both bypass sharing exactly - // as they bypass the pool, and their behaviour stays byte-identical to pre-stage-6. + // as they bypass the pool, and their behavior stays byte-identical to pre-stage-6. const Bool runOnPool = m_preprocessCache && MG_Util::Async::AsyncShaderCompileActive(); const Uint64 sourceHash = ShaderPreprocessCache::HashSource(*m_source); diff --git a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h index 5c463b1b..487d6496 100644 --- a/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h +++ b/MobileGL/MG_State/GLState/ProgramState/ShaderObject.h @@ -110,13 +110,13 @@ namespace MobileGL { // so the verdict is recorded directly - COMPILE_STATUS false with this log - and both // queries answer from it without touching the compile pipeline. void RecordSpecializationFailure(String&& infoLog); - // Gives up this object's claim on its compile node, cancelling the node only if + // Gives up this object's claim on its compile node, canceling the node only if // this object was its LAST claimant. Called at the points where the object's // compiled state stops being observable through THIS name: a real source change, // and the release of an orphaned shader name. // // Named for what it does rather than for what it used to do: before stage 6 a - // node had exactly one shader object, so giving up the claim and cancelling the + // node had exactly one shader object, so giving up the claim and canceling the // compile were the same act and this was CancelCompile(). They are not the same // act any more - see ShaderCompileTask::AddAdopter for the count discipline and // its single-threadedness argument. Never waits, in either case. @@ -171,7 +171,7 @@ namespace MobileGL { // Tri-state, and deliberately NOT joining: an in-flight compile of the current // source counts as memoized (a second glCompileShader must not enqueue a // duplicate job), but asking that question must never block. - // A node that settled as Cancelled (the job body threw, or the enqueue failed) + // A node that settled as Canceled (the job body threw, or the enqueue failed) // carries no result, so it must NOT satisfy the memo: otherwise a second // glCompileShader on the same source enqueues nothing and the eventual join // reports GL_FALSE forever. The synchronous path retries in exactly this case. @@ -219,7 +219,7 @@ namespace MobileGL { void JoinPendingCompile() const; // The artifacts of a compile that ran to completion. A node that was abandoned - // (cancelled at teardown, or whose body threw) never publishes: JoinPendingCompile + // (canceled at teardown, or whose body threw) never publishes: JoinPendingCompile // drops it, so anything reachable here is either Complete or absent, and "absent" // reads as the never-compiled defaults - COMPILE_STATUS false, empty info log, // which is exactly what GL requires before the first glCompileShader. diff --git a/MobileGL/MG_State/GLState/RenderState/RenderState.h b/MobileGL/MG_State/GLState/RenderState/RenderState.h index 769d5e95..6da4699f 100644 --- a/MobileGL/MG_State/GLState/RenderState/RenderState.h +++ b/MobileGL/MG_State/GLState/RenderState/RenderState.h @@ -170,13 +170,13 @@ namespace MobileGL { Uint16 m_version = 0; // Only the subset of render state that a backend bakes INTO a pipeline object. - // Viewport, scissor, depth range, blend colour, line width, polygon offset, stencil + // Viewport, scissor, depth range, blend color, line width, polygon offset, stencil // write mask, the clear values, hints and the point-size family are all either // dynamic pipeline state or not pipeline state at all, so changing one of them must // not evict a cached pipeline. Keeping one counter for both made a glViewport call // knock the next draw off the pipeline memo AND the draw fast path. Uint16 m_pipelineStateVersion = 0; - // Value-initialised, PADDING INCLUDED. The MGPipe CSO key is a byte-range + // Value-initialized, PADDING INCLUDED. The MGPipe CSO key is a byte-range // hash over RenderStateParameters and the residual block's trip wire is a // byte-level compare, so indeterminate padding would make a CSO handle // reproducible only within one context and would make the trip wire diff --git a/MobileGL/MG_State/GLState/SamplerState/SamplerObject.cpp b/MobileGL/MG_State/GLState/SamplerState/SamplerObject.cpp index 2cb6c997..34990abc 100644 --- a/MobileGL/MG_State/GLState/SamplerState/SamplerObject.cpp +++ b/MobileGL/MG_State/GLState/SamplerState/SamplerObject.cpp @@ -183,14 +183,14 @@ namespace MobileGL { return m_samplerParameters.maxAnisotropy; } - // The three border-colour representations are kept in step so a getter of any form has + // The three border-color representations are kept in step so a getter of any form has // an answer whichever form was written. Integer <-> float uses the plain value, matching // what glTexParameterIiv/Iuiv mean: those forms are for integer texture formats, whose // border components are the raw integers rather than a normalized fraction. // // Which of the three the application actually WROTE is recorded separately in // borderColorForm, because the derived values erase it: a backend has to know whether to - // forward the colour through glSamplerParameterfv or glSamplerParameterIiv (and which + // forward the color through glSamplerParameterfv or glSamplerParameterIiv (and which // VkBorderColor family to ask Vulkan for), and the numbers alone cannot say. That is also // why every setter's early-out tests the form as well as the value - a float (0,0,0,1) // followed by an integer (0,0,0,1) is a real state change even though nothing numeric diff --git a/MobileGL/MG_State/GLState/TextureState/MipmapStorage.cpp b/MobileGL/MG_State/GLState/TextureState/MipmapStorage.cpp index e216b9a3..51129858 100644 --- a/MobileGL/MG_State/GLState/TextureState/MipmapStorage.cpp +++ b/MobileGL/MG_State/GLState/TextureState/MipmapStorage.cpp @@ -526,7 +526,7 @@ namespace MobileGL { return; } EnterFootprintLog(level, incoming); - // Full: fold the incoming rect into the neighbour whose box grows least + // Full: fold the incoming rect into the neighbor whose box grows least // (least new area dragged into the upload), then re-insert the grown // box - it may now touch others. The removal above guarantees the // recursion appends on the second pass at the latest. diff --git a/MobileGL/MG_State/GLState/TextureState/MipmapStorage.h b/MobileGL/MG_State/GLState/TextureState/MipmapStorage.h index 6774c07e..0e103656 100644 --- a/MobileGL/MG_State/GLState/TextureState/MipmapStorage.h +++ b/MobileGL/MG_State/GLState/TextureState/MipmapStorage.h @@ -70,7 +70,7 @@ namespace MobileGL { // list forced into far-apart merges was measured at >90% of the union // box's area on exactly that pattern, i.e. worthless. Inserts merge any // touching/overlapping rect (cascading, so the list stays disjoint); - // when full, the incoming rect folds into the neighbour whose box grows + // when full, the incoming rect folds into the neighbor whose box grows // least and the list degrades gracefully toward the union box. static constexpr SizeT kMaxDirtyRects = 96; // Copies the level's dirty rects into outRects and returns how many were diff --git a/MobileGL/MG_State/GLState/TextureState/TextureObject.cpp b/MobileGL/MG_State/GLState/TextureState/TextureObject.cpp index eb174301..ee4415f9 100644 --- a/MobileGL/MG_State/GLState/TextureState/TextureObject.cpp +++ b/MobileGL/MG_State/GLState/TextureState/TextureObject.cpp @@ -150,7 +150,7 @@ namespace MobileGL { // NOTHING THE DERIVED CLASS IMPLEMENTS IS TOUCHED HERE and that is a // correctness requirement rather than a style: the derived object does not exist // yet, so ITextureObject::GetStorageType and ::GetUploadTargets - PURE, with no - // body on this base - would be undefined behaviour. The emitter reads GetTarget() + // body on this base - would be undefined behavior. The emitter reads GetTarget() // and GetExternalIndex(), which TextureObjectBase itself overrides and which // therefore dispatch to this class's own bodies over members the mem-init list // has already written; the storage kind is derived from the target, which is @@ -400,7 +400,7 @@ namespace MobileGL { ++m_textureParamsVersion; MGP_NOTE_AGGREGATE(TextureParams); // Immutable is a descriptor fact the backend reads - and NOT a request for an - // acknowledgement: MGPipeResourceRespecifyNeedsAck names the buffer target + // acknowledgment: MGPipeResourceRespecifyNeedsAck names the buffer target // explicitly, because texture allocation is lazy in monolith and stays lazy in // split. The level clamp above is params. PipePublishDescriptor(); diff --git a/MobileGL/MG_Test/Backend/BackendObjectEglStateTest.cpp b/MobileGL/MG_Test/Backend/BackendObjectEglStateTest.cpp index 6bef2f5a..eb594105 100644 --- a/MobileGL/MG_Test/Backend/BackendObjectEglStateTest.cpp +++ b/MobileGL/MG_Test/Backend/BackendObjectEglStateTest.cpp @@ -915,7 +915,7 @@ TEST_F(BackendObjectEglRegister, APbufferNeedsADisplayASurfaceAndAPositiveExtent EXPECT_TRUE(Trace().empty()); } -// Re-registering replaces the whole record. A pending destroy is cancelled and +// Re-registering replaces the whole record. A pending destroy is canceled and // Activated is reset (the next real activation re-probes); the active view is left as it was. TEST_F(BackendObjectEglRegister, ReRegisteringReplacesTheWholeRecord) { ASSERT_TRUE(Init()); @@ -930,7 +930,7 @@ TEST_F(BackendObjectEglRegister, ReRegisteringReplacesTheWholeRecord) { EXPECT_TRUE(WindowIs(b->WindowHandleNow(), kWin1)); EXPECT_TRUE(b->CapsProbed()); EXPECT_TRUE(Trace().empty()); - // The cancelled destroy does not complete when the binding goes. + // The canceled destroy does not complete when the binding goes. EXPECT_TRUE(Release()); EXPECT_TRUE(b->IsRegistered(kS1)); EXPECT_TRUE(Trace().empty()); diff --git a/MobileGL/MG_Test/Backend/DirectGLES/EsslShaderPassTest.cpp b/MobileGL/MG_Test/Backend/DirectGLES/EsslShaderPassTest.cpp index 836e09d1..b1db6c17 100644 --- a/MobileGL/MG_Test/Backend/DirectGLES/EsslShaderPassTest.cpp +++ b/MobileGL/MG_Test/Backend/DirectGLES/EsslShaderPassTest.cpp @@ -814,7 +814,7 @@ void main() EXPECT_FALSE(Contains(out, "g_image[")) << out; } -// ...and the suffix is not a licence to accept anything else that ends in one: `iu` is not a +// ...and the suffix is not a license to accept anything else that ends in one: `iu` is not a // literal, and neither is a bare `u`. TEST(RemapImageArrayElementUnitsTest, ASuffixAloneDoesNotMakeAnExpressionALiteral) { const String source = R"(#version 320 es @@ -919,7 +919,7 @@ void main() // image ARRAY, and the regression it caused was in the SCALAR images sitting next to one. A // scalar with an explicit binding has to come out of the whole chain still on ITS OWN unit, // still spelled once, and named the same thing every stage would name it - it is the array that -// needs repairing, not its neighbour. +// needs repairing, not its neighbor. TEST(RemapImageArrayElementUnitsTest, AScalarImageWithItsOwnBindingIsUntouchedByTheArrayRepair) { const String source = R"(#version 320 es layout(rgba8, binding = 7) uniform highp image2D goku; @@ -1226,7 +1226,7 @@ void main() { imageStore(uni_image, ivec2(0), uvec4(1u)); } } // Never speculatively: `#extension` naming an extension the driver does not advertise is itself a -// compile error, so the caller's "not needed" answer has to be honoured exactly. +// compile error, so the caller's "not needed" answer has to be honored exactly. TEST(RequestExtendedImageFormatsTest, NotNeededMeansNotEmitted) { const String source = R"(#version 320 es layout(rgba8ui, binding = 1) uniform writeonly highp uimage2D uni_image; @@ -1262,7 +1262,7 @@ void main() { gl_ViewportIndex = gl_InvocationID; EmitVertex(); } } // Never speculatively: ARM's compiler hard-errors on an `#extension` naming a string the driver -// does not advertise, so the caller's "not needed" answer has to be honoured exactly. A driver +// does not advertise, so the caller's "not needed" answer has to be honored exactly. A driver // without the extension gets the LowerViewportIndexPass fallback instead. TEST(RequestViewportArrayExtensionTest, NotNeededMeansNotEmitted) { const String source = R"(#version 320 es @@ -1377,7 +1377,7 @@ void main() { gl_ViewportIndex = 1; gl_PointSize = 2.0; EmitVertex(); } // Desktop GL makes the tessellation control stage optional and takes the levels from // PATCH_DEFAULT_OUTER_LEVEL / PATCH_DEFAULT_INNER_LEVEL; ES 3.2 has neither, and rejects a // program that has an evaluation stage without a control stage - with an EMPTY info log. The -// synthesized stage is what stands in, and it has to MIRROR its two neighbours' gl_PerVertex +// synthesized stage is what stands in, and it has to MIRROR its two neighbors' gl_PerVertex // rather than pick a shape, because a redeclaration that disagrees with the stage it feeds is an // ES link error against a program that has nothing else wrong with it. @@ -1386,7 +1386,7 @@ namespace { const FloatVec2 kDefaultInner(1.0f, 1.0f); } // namespace -// The synthesized stage mirrors its neighbours' gl_PerVertex, so it can be the thing that +// The synthesized stage mirrors its neighbors' gl_PerVertex, so it can be the thing that // declares gl_PointSize - and in ESSL a redeclaration is exactly as illegal as a reference // without the extension. The directive has to survive being applied to its output. TEST(RequestPointSizeExtensionTest, CoversAMirroredPassthroughControlStage) { @@ -1411,7 +1411,7 @@ TEST(PassthroughTessControlEsslTest, DeclaresThePatchSizeAndWritesEveryTessLevel "gl_TessLevelOuter[3]", "gl_TessLevelInner[0]", "gl_TessLevelInner[1]"}) { EXPECT_TRUE(Contains(out, String(level) + " = 1.0;")) << level << "\n" << out; } - // Nothing redeclared when the neighbours redeclared nothing - the driver's own built-in + // Nothing redeclared when the neighbors redeclared nothing - the driver's own built-in // gl_in/gl_out is then what both sides agree on, and redeclaring is what would break it. EXPECT_FALSE(Contains(out, "gl_PerVertex")) << out; } diff --git a/MobileGL/MG_Test/Backend/DirectGLES/NarrowIntegerEsslTest.cpp b/MobileGL/MG_Test/Backend/DirectGLES/NarrowIntegerEsslTest.cpp index 1f87db3a..72a1e40f 100644 --- a/MobileGL/MG_Test/Backend/DirectGLES/NarrowIntegerEsslTest.cpp +++ b/MobileGL/MG_Test/Backend/DirectGLES/NarrowIntegerEsslTest.cpp @@ -9,7 +9,7 @@ // A vertex stage armed with the narrow-integer seeds, through the same steps the DirectGLES build // takes: the array-input split, the RuntimeWidths pass, ESSL 3.00 emission and the uniform // promotion. The two widths have to come out as `uniform highp uint` (anything else is read -// uninitialised or at too low a precision) and the result has to be ESSL 3.00 a compiler accepts. +// uninitialized or at too low a precision) and the result has to be ESSL 3.00 a compiler accepts. // The emission here uses plain ESSL 3.00 options, not the build's whole pass chain; the // integration lanes run that chain (NarrowIntegerAttributeScenario). @@ -95,7 +95,7 @@ void main() { color = vec4(a) + vec4(b); } return result != nullptr ? String(result) : String{}; } - // Declarations of `name` as a uint, whatever their qualifiers or initialiser. + // Declarations of `name` as a uint, whatever their qualifiers or initializer. SizeT CountUintDeclarations(const String& source, const char* name) { SizeT count = 0; for (const char* suffix : {";", " ="}) { diff --git a/MobileGL/MG_Test/Backend/DirectGLES/ViewportIndexRoutingTest.cpp b/MobileGL/MG_Test/Backend/DirectGLES/ViewportIndexRoutingTest.cpp index 5959d4ba..2f1a7982 100644 --- a/MobileGL/MG_Test/Backend/DirectGLES/ViewportIndexRoutingTest.cpp +++ b/MobileGL/MG_Test/Backend/DirectGLES/ViewportIndexRoutingTest.cpp @@ -170,7 +170,7 @@ void main() // A stage the pass declines must reach the driver exactly as it arrived, not half-rewritten. // The caller logs the decline and the program still renders - unrouted, which is the old -// behaviour - so a partially edited source here would turn a degradation into a broken shader. +// behavior - so a partially edited source here would turn a degradation into a broken shader. TEST(ViewportIndexRoutingTest, AStageWithNoEntryPointIsDeclinedWithoutBeingEdited) { const String before = "#version 320 es\nprecision highp int;\nhighp int f() { return gl_ViewportIndex; }\n"; String source = before; diff --git a/MobileGL/MG_Test/BackendLoader/BackendLoaderTest.cpp b/MobileGL/MG_Test/BackendLoader/BackendLoaderTest.cpp index 32fe83ac..e40413e3 100644 --- a/MobileGL/MG_Test/BackendLoader/BackendLoaderTest.cpp +++ b/MobileGL/MG_Test/BackendLoader/BackendLoaderTest.cpp @@ -38,7 +38,7 @@ namespace { // Behavior knobs, configured per test before running the probe. GLint maxVertexSsboBlocks = 4; // GL_MAX_COMPUTE_WORK_GROUP_COUNT / _SIZE per axis, answered through glGetIntegeri_v. - // Above the GL minimums and distinct per axis, so a loader that left an initialiser in + // Above the GL minimums and distinct per axis, so a loader that left an initializer in // place or copied one axis into another is caught. GLint maxComputeWorkGroupCount[3] = {70001, 70002, 70003}; GLint maxComputeWorkGroupSize[3] = {1500, 1501, 100}; @@ -463,7 +463,7 @@ namespace { // ---- what the located-interface-block probe draws with ------------------------- // Enough of a rasterizer for ProbeLocatedIoBlocksLosePayload to reach a verdict: it // builds three programs, draws each to a 1x1 target and reads the pixel back, and the - // fake decides what each read returns. Default behaviour is a CONFORMING driver, so + // fake decides what each read returns. Default behavior is a CONFORMING driver, so // every test that predates this one sees the probe reach "not affected" and no // capability it asserts on moves. funcs.glCheckFramebufferStatus = [](GLenum) -> GLenum { return GL_FRAMEBUFFER_COMPLETE; }; @@ -1724,7 +1724,7 @@ TEST(LocatedIoBlockProbe, ReportsTheDefectOnlyWhenTheUnlocatedControlCarriesTheP // The six per-axis compute limits are the backend-owned answers that cross the MGPipe boundary // inside MGPCaps (DynamicBackendParameters::MaxComputeWorkGroupCount/Size), so the loader has -// to take EACH axis from glGetIntegeri_v rather than leave an initialiser - or one axis's +// to take EACH axis from glGetIntegeri_v rather than leave an initializer - or one axis's // answer - in the other slots. The integration side (AdvertisedLimitsScenario) pins the copy // against the live getter on both backends; this pins the driver-to-caps step on its own. TEST(ComputeWorkGroupCapabilities, TakesEveryAxisFromTheIndexedQuery) { @@ -1736,8 +1736,8 @@ TEST(ComputeWorkGroupCapabilities, TakesEveryAxisFromTheIndexedQuery) { EXPECT_EQ(caps.MaxComputeWorkGroupCount[axis], g_fake.maxComputeWorkGroupCount[axis]) << "axis " << axis; EXPECT_EQ(caps.MaxComputeWorkGroupSize[axis], g_fake.maxComputeWorkGroupSize[axis]) << "axis " << axis; } - // The initialisers are the GL 4.3 minimums and every fake answer is above them, so a - // value equal to its initialiser here would mean the query never ran. + // The initializers are the GL 4.3 minimums and every fake answer is above them, so a + // value equal to its initializer here would mean the query never ran. EXPECT_GT(caps.MaxComputeWorkGroupCount[0], 65535); EXPECT_GT(caps.MaxComputeWorkGroupSize[2], 64); } diff --git a/MobileGL/MG_Test/Buffer/BufferTest.cpp b/MobileGL/MG_Test/Buffer/BufferTest.cpp index f3daaf8f..7218612c 100644 --- a/MobileGL/MG_Test/Buffer/BufferTest.cpp +++ b/MobileGL/MG_Test/Buffer/BufferTest.cpp @@ -1419,7 +1419,7 @@ TEST_F(GeneralBufferTest, General_PersistentExplicitFlushOnlyDirtiesFlushedRange // The explicit flush is what GL 4.6 6.2.1 promises reaches the store. (Until P13 W6 this also // asserted that a per-draw sync moved nothing; the record arm's push publishes the map itself, - // so that was the deleted frontend arm's behaviour, not a rule.) + // so that was the deleted frontend arm's behavior, not a rule.) FlushMappedBufferRange(GL_ARRAY_BUFFER, sizeof(GLint), sizeof(GLint)); EXPECT_GT(bufferObject->GetChangeSerial(), baseSerial); @@ -2019,7 +2019,7 @@ TEST_F(BufferTest, RedefiningANonAdoptedBufferIsUnchanged) { // in place and never has a staging copy - so the unmap simply skipped the copy-back // for a resident store. Residency now also comes from a shader storage binding // (EnsureGpuResidentStorage at draw time) and from large-store adoption, both of which -// an application then re-initialises through an ordinary map/write/unmap: the +// an application then re-initializes through an ordinary map/write/unmap: the // conformance suite re-seeds every SSBO that way before each draw, and every re-seed // after the first draw was dropped on the floor. These pin the landing for each map // shape, on the backend that writes the coherent mapping in place and on the one that diff --git a/MobileGL/MG_Test/Buffer/SplitBufferTest.cpp b/MobileGL/MG_Test/Buffer/SplitBufferTest.cpp index 12eac427..eb957fab 100644 --- a/MobileGL/MG_Test/Buffer/SplitBufferTest.cpp +++ b/MobileGL/MG_Test/Buffer/SplitBufferTest.cpp @@ -208,7 +208,7 @@ TEST_F(SplitBufferSet, Row2AWritableImageBufferTextureIsMarkedByADraw) { binding = MG_State::GLState::ImageTextureBinding{}; } -// Row 2's BOUND, and it is the half an optimisation is allowed to get wrong in exactly one +// Row 2's BOUND, and it is the half an optimization is allowed to get wrong in exactly one // direction (P5d round 3, package C). The sweep used to be MAX_TEXTURE_IMAGE_UNITS wide on every // draw - 2.15% self of the GL thread on the Minecraft inproc profile, in a workload with no image // binding anywhere - and is now bounded by the frontend's image-unit high-water mark. @@ -376,7 +376,7 @@ TEST_F(SplitBufferSet, TheAdoptedArmIsNotAMemberAndItIsTheChainRowThatSaysSo) { // The SET agrees with the predicate, asked through the production entry point rather than by // reading a member: NoteMapStateChanged is what every one of the five maintenance events - // calls, and it must refuse to enrol an adopted store. + // calls, and it must refuse to enroll an adopted store. PersistentMapTracker::Instance().NoteMapStateChanged(*adopted); EXPECT_EQ(PersistentMapTracker::Instance().MemberCount(), 1u) << "only the declined twin: enrolling an adopted store would make the push read its " diff --git a/MobileGL/MG_Test/Framebuffer/FramebufferTest.cpp b/MobileGL/MG_Test/Framebuffer/FramebufferTest.cpp index 61e033b4..b0e3fc6b 100644 --- a/MobileGL/MG_Test/Framebuffer/FramebufferTest.cpp +++ b/MobileGL/MG_Test/Framebuffer/FramebufferTest.cpp @@ -843,7 +843,7 @@ TEST_F(FramebufferTest, NonRenderableColorFormatsReportUnsupportedFramebuffer) { EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_INVALID_FRAMEBUFFER_OPERATION); } -// ---- Three-channel colour attachments: the Complementary Reimagined / Iris load failure -------- +// ---- Three-channel color attachments: the Complementary Reimagined / Iris load failure -------- // // Complementary declares colortex1 = RGB8_SNORM and colortex2 = RGB16F. No real OpenGL ES driver // renders to a three-channel image (EXT_render_snorm covers R/RG/RGBA only; EXT_color_buffer_float @@ -929,7 +929,7 @@ namespace { } // namespace TEST_F(FramebufferTest, ThreeChannelColorAttachmentsAreUnsupportedWithoutTheWidenedSubstitution) { - // The pre-fix behaviour, pinned so a regression is a red test rather than a shaderpack that + // The pre-fix behavior, pinned so a regression is a red test rather than a shaderpack that // silently stops loading: no caveat capability, so nothing makes these renderable. ScopedBackendOverride backend(MakeUnique(/*substituted=*/false)); @@ -987,7 +987,7 @@ TEST_F(FramebufferTest, TwoAttachmentCompositeFramebufferMatchesIrisComplementar // buffer's alpha write mask forced off so nothing can move it again. // // These cases pin the two halves of that pairing at the seam where they are visible - what the ES -// driver is actually handed - and pin the invariant that the application's own colour mask is +// driver is actually handed - and pin the invariant that the application's own color mask is // never touched. namespace { struct RecordedColorMask { @@ -1246,7 +1246,7 @@ TEST_F(FramebufferTest, ClearIntoAWidenedDrawBufferKeepsAlphaWritableAndSubstitu MG_Test::ScopedPipeVerb clear(MG_Pipe::MGPipeVerb::Clear); MG_Backend::DirectGLES::RenderStateImpl::SyncRenderState(/*forColorClear=*/true); } - ASSERT_TRUE(g_driverIndexedColorMasks[1].seen) << "the clear must re-push the colour mask"; + ASSERT_TRUE(g_driverIndexedColorMasks[1].seen) << "the clear must re-push the color mask"; EXPECT_EQ(g_driverIndexedColorMasks[1].a, GL_TRUE) << "a clear is what puts the 1.0 in the stored alpha"; // The value that clear writes: the application's RGB, alpha replaced by the 1.0 the @@ -1446,7 +1446,7 @@ TEST_F(FramebufferTest, DualSourceFactorsAreDeclinedEvenWithBlendingDisabled) { } // A clear reaches the same block by the same route (SyncRenderState(forColorClear=true)), and - // the flag only steers the alpha-widen colour mask, so it must not reopen this either. + // the flag only steers the alpha-widen color mask, so it must not reopen this either. MG_Impl::GLImpl::BlendFunc(GL_SRC1_COLOR, GL_ONE_MINUS_SRC1_COLOR); ResetRecordedBlend(); { @@ -1529,7 +1529,7 @@ TEST_F(FramebufferTest, FramebufferTextureRejectsAColourAttachmentPastTheLimit) ? static_cast(MG_Backend::pActiveBackendObject->GetDynamicParameters().MaxColorAttachments) : static_cast(MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS); ASSERT_GT(limit, 0); - ASSERT_LT(limit, 32) << "the test needs a colour attachment enum past the limit to exist"; + ASSERT_LT(limit, 32) << "the test needs a color attachment enum past the limit to exist"; MG_Impl::GLImpl::FramebufferTexture(GL_DRAW_FRAMEBUFFER, static_cast(GL_COLOR_ATTACHMENT0 + limit), texture, 0); @@ -1584,7 +1584,7 @@ TEST_F(FramebufferTest, FramebufferTextureRejectsALevelTheTextureDoesNotHave) { // than through the shared helper - so each of them has to be asked separately or one entry point // answers differently from its aliases. glFramebufferTexture2D is the most-used of the five, and // the default-framebuffer case is the damaging one: the attach used to succeed and replace -// framebuffer 0's colour attachment, which nothing ever puts back. +// framebuffer 0's color attachment, which nothing ever puts back. TEST_F(FramebufferTest, FramebufferTexture2DRejectsTheDefaultFramebufferAndBadAttachments) { GLuint texture = 0; @@ -1606,7 +1606,7 @@ TEST_F(FramebufferTest, FramebufferTexture2DRejectsTheDefaultFramebufferAndBadAt EXPECT_EQ(colorAfter.IsTexture(), hadTextureBefore); if (colorAfter.IsTexture() && hadTextureBefore) { EXPECT_NE(colorAfter.GetTexture()->GetExternalIndex(), texture) - << "the refused attach must not have replaced framebuffer 0's colour attachment"; + << "the refused attach must not have replaced framebuffer 0's color attachment"; } GLuint framebuffer = 0; diff --git a/MobileGL/MG_Test/Pipe/CompositeResolverTest.cpp b/MobileGL/MG_Test/Pipe/CompositeResolverTest.cpp index f1303b0f..56c8dc1c 100644 --- a/MobileGL/MG_Test/Pipe/CompositeResolverTest.cpp +++ b/MobileGL/MG_Test/Pipe/CompositeResolverTest.cpp @@ -65,7 +65,7 @@ #include #include #include -// create_shader_state takes the two artefact structs by pointer beside the record, so a case +// create_shader_state takes the two artifact structs by pointer beside the record, so a case // that mints a composite record needs their definitions. #include diff --git a/MobileGL/MG_Test/Pipe/FieldOwnershipTest.cpp b/MobileGL/MG_Test/Pipe/FieldOwnershipTest.cpp index 5fb142dd..4d7eb979 100644 --- a/MobileGL/MG_Test/Pipe/FieldOwnershipTest.cpp +++ b/MobileGL/MG_Test/Pipe/FieldOwnershipTest.cpp @@ -13,7 +13,7 @@ // the ARITHMETIC cases run in any push build and say the table PARTITIONS the field set - // 70 rows, four classes, every BARRIER-PULLED row naming the phase that retires it; // -// the BEHAVIOUR cases run only in a split build and say the table is LOAD-BEARING - that a +// the BEHAVIOR cases run only in a split build and say the table is LOAD-BEARING - that a // server verb stamp makes the record-supplied fields readable and withdraws the rest, that a // retired pointer/forward reads are unconditionally named Fatal on the server, and that // monolith storage remains readable without ever borrowing a server stamp. @@ -359,7 +359,7 @@ TEST_F(FieldOwnershipTest, TheAdmittedPullTableIsID84sDerivationAndNotAList) { } // --------------------------------------------------------------------------------------- -// The behaviour: the table is load-bearing. Split builds only - it is the server verb stamp +// The behavior: the table is load-bearing. Split builds only - it is the server verb stamp // that arms all of it, and nothing in a monolith lane stamps. // --------------------------------------------------------------------------------------- @@ -371,7 +371,7 @@ TEST_F(FieldOwnershipTest, TheAdmittedPullTableIsID84sDerivationAndNotAList) { // not an abort: the walk stamps FilledGen from the verb serial whether or not it copied, so the // field reads FRESH with the previous verb's value and the draw goes out with a stale binding // slot. Poison catches an UNSTAMPED read; it cannot catch a stamped-but-uncopied one. That is -// exactly why this case exists - there is no second line of defence behind it. +// exactly why this case exists - there is no second line of defense behind it. // // So each input is moved on its own with the answer read back in between, and in an order where // a memo that ignored that input would have to return the stale answer rather than the right one @@ -461,7 +461,7 @@ TEST_F(FieldOwnershipTest, TheResidualFillsSuppliedMemoReKeysOnEveryInputThatMov EXPECT_EQ(MGPipeFieldMaskHas(withConsumer, field), MGPipeFieldMaskHas(withoutConsumer, field)) << kMGPipeInputFieldNames[i] << "'s supplied answer moved with the P4a consumer signal. That is CORRECT " - "behaviour and this assertion is a trip wire, not a defect report: the " + "behavior and this assertion is a trip wire, not a defect report: the " "conjunct stopped being dominated, so the memo's fourth key input is now " "observable and needs the move-it-and-read-it-back pair steps 1-3 give the " "other three - under split through CapsMirrorInstance().Adopt() with and " @@ -510,7 +510,7 @@ TEST_F(FieldOwnershipTest, AServerStampMakesRecordSuppliedFieldsFreshAndWithdraw EXPECT_FALSE(MGPipeInputFieldIsFresh(filled, MGPipeInputField::RecordError)); // sticky } -// THE STICKY EXEMPTION, CANCELLED. generated/PipeFilled.inc answers "fresh" for a sticky field +// THE STICKY EXEMPTION, CANCELED. generated/PipeFilled.inc answers "fresh" for a sticky field // whatever the serial says - but it tests "never filled" FIRST, so the stamp's withdrawal // (FilledGen = 0) wins over kMGPipeInputFieldSticky without a line of the generated file // changing. Before this, the seven most dangerous fields were exempt by construction. @@ -628,7 +628,7 @@ TEST_F(FieldOwnershipTest, AStickyForwardIsCountedAsAResidualPull) { } // ... and outside a server-stamped verb they are ordinary monolith calls, which is what keeps -// InvalidateCompileEnv reachable from backend initialisation - the case the exemption exists +// InvalidateCompileEnv reachable from backend initialization - the case the exemption exists // for - and what keeps build-split's monolith lanes behaving as a verify build's do. TEST_F(FieldOwnershipTest, NothingIsCountedOutsideAServerStampedVerb) { MGPipeValidateForVerb(MGPipeVerb::ReadPixels); @@ -643,7 +643,7 @@ TEST_F(FieldOwnershipTest, NothingIsCountedOutsideAServerStampedVerb) { // server MG_Impl is not in the process, so MGPipeValidateForVerb/MGPipeLeaveVerb never run and // MGPipeServerClearVerbBoundary is the ONLY thing that can disarm the flag; without it the // server latches TRUE after its first stamp and the sticky exemption - the one -// InvalidateCompileEnv is reached from backend initialisation under - is gone for good. +// InvalidateCompileEnv is reached from backend initialization under - is gone for good. TEST_F(FieldOwnershipTest, TheAppliersOwnClearDisarmsTheStampWithoutTheClientsFill) { MGPipeServerStampVerbBoundary(MGPipeVerb::ReadPixels); ASSERT_TRUE(gPipeInputs->ServerStampedVerb()); @@ -864,7 +864,7 @@ TEST_F(FieldOwnershipTest, RoleSplitGivesTheFillSideADistinctBlockTheStampNeverT // And the server block's identity is server-owned under the rehearsal (§3.2's other half): // the stamp set it, and it is non-null - a null identity reads as a hit against - // DirectGLES' zero-initialised fb-slot memo cache, which is the unnamed crash this line + // DirectGLES' zero-initialized fb-slot memo cache, which is the unnamed crash this line // exists to preclude. EXPECT_NE(gPipeInputs->ContextIdentity(), nullptr); } diff --git a/MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp b/MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp index efdc2b75..17df3f6c 100644 --- a/MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/FramebufferEmitTest.cpp @@ -377,7 +377,7 @@ TEST(FramebufferEmit, OneObjectBoundToBothTargetsEmitsOneRecordWithTargetBoth) { // array, at the verb, from the framebuffer state it then holds - precisely so a program can // relink inside the same draw. A hash that did not cover the array would let a suppressed // set_framebuffer_state mean "the draw buffers did not move" when they had, and the shader -// would be specialised for the previous output shape. +// would be specialized for the previous output shape. TEST(FramebufferEmit, ADrawBufferChangeAloneStillMovesTheContentHash) { FramebufferScope scope; const auto color0 = MakeColorTexture(6, 32); @@ -472,21 +472,21 @@ TEST(FramebufferEmit, EveryAttachmentFieldSurvivesTheSurfaceConversion) { const MGPSurface& surface = record.Color[i]; const MGPipeHandle expected = MGPipeSlots().FindByLifetimeId(MGPipeKind::Texture, attachment.GetTexture()->GetLifetimeId()); - EXPECT_TRUE(surface.Res == expected) << "MGPSurface::Res at colour point " << i; - EXPECT_EQ(surface.Kind, kMGPipeSurfaceKindTexture) << "MGPSurface::Kind at colour point " << i; + EXPECT_TRUE(surface.Res == expected) << "MGPSurface::Res at color point " << i; + EXPECT_EQ(surface.Kind, kMGPipeSurfaceKindTexture) << "MGPSurface::Kind at color point " << i; EXPECT_EQ(surface.InternalFormat, static_cast(attachment.GetTexture()->GetFormat())) - << "MGPSurface::InternalFormat at colour point " << i; + << "MGPSurface::InternalFormat at color point " << i; EXPECT_EQ(surface.Level, static_cast(attachment.GetTextureLevel())) - << "MGPSurface::Level at colour point " << i; + << "MGPSurface::Level at color point " << i; EXPECT_EQ(surface.Layer, static_cast(attachment.GetTextureLayer())) - << "MGPSurface::Layer at colour point " << i; - EXPECT_EQ(surface.Layered, attachment.IsLayered() ? 1 : 0) << "MGPSurface::Layered at colour point " << i; + << "MGPSurface::Layer at color point " << i; + EXPECT_EQ(surface.Layered, attachment.IsLayered() ? 1 : 0) << "MGPSurface::Layered at color point " << i; EXPECT_EQ(surface.UploadTarget, static_cast(TextureUploadTarget::Texture2D)) - << "MGPSurface::UploadTarget at colour point " << i; + << "MGPSurface::UploadTarget at color point " << i; // ID-12 DV-5: three of the four cross-object masks reduce to (format, TEXTURE TARGET) // and no TextureUploadTarget -> TextureTarget inverse exists anywhere in the tree. EXPECT_EQ(surface.TextureTarget, static_cast(attachment.GetTexture()->GetTarget())) - << "MGPSurface::TextureTarget at colour point " << i; + << "MGPSurface::TextureTarget at color point " << i; } EXPECT_EQ(record.Depth.Kind, kMGPipeSurfaceKindRenderbuffer) << "MGPSurface::Kind on the depth point"; @@ -552,7 +552,7 @@ TEST(FramebufferEmit, AnAttachmentPointAboveTheWireWidthIsRefusedNotTruncated) { // THE SERVER TWIN of AnAttachmentPointAboveTheWireWidthIsRefusedNotTruncated above. // // That case pins the CLIENT half: a framebuffer holding a point at or above the wire width is -// refused rather than truncated. P5e turns that refusal into a licence the server SPENDS - the +// refused rather than truncated. P5e turns that refusal into a license the server SPENDS - the // by-handle attachment walk stopped iterating the frontend's 41 points and now walks // Color[0..7] + Depth + Stencil and nothing else, on the argument that the record's eleven // surfaces ARE the point set. So the statement the server relies on needs a case of its own, @@ -566,7 +566,7 @@ TEST(FramebufferEmit, AnAttachmentPointAboveTheWireWidthIsRefusedNotTruncated) { // // Half 2 is the one that would go quiet on its own. A truncating emitter would still refuse // nothing, publish a record, and leave the server's walk perfectly self-consistent over eight -// colour points while one attachment silently stopped existing. +// color points while one attachment silently stopped existing. TEST(FramebufferEmit, TheRecordsElevenSurfacesAreTheWholePointSetTheServerReads) { FramebufferScope scope; const auto fbo = MakeShared(21); @@ -589,7 +589,7 @@ TEST(FramebufferEmit, TheRecordsElevenSurfacesAreTheWholePointSetTheServerReads) Framebuffers().EmitFramebufferState(Ctx()); ASSERT_EQ(Framebuffers().RefusedCount(), 0u) << "a full but legal framebuffer was refused"; - // The wire's colour width and the server's walk width are ONE number. + // The wire's color width and the server's walk width are ONE number. static_assert(std::size(MGPFramebufferState{}.Color) == kMGPipeMaxColorAttachments, "the server walks Color[0..kMGPipeMaxColorAttachments); the array must be that wide"); @@ -597,9 +597,9 @@ TEST(FramebufferEmit, TheRecordsElevenSurfacesAreTheWholePointSetTheServerReads) ASSERT_NE(applied, nullptr); for (Uint i = 0; i < kMGPipeMaxColorAttachments; ++i) { const MGPipeHandle expected = MGPipeSlots().FindByLifetimeId(MGPipeKind::Texture, colors[i]->GetLifetimeId()); - EXPECT_FALSE(MGPipeHandleIsNull(expected)) << "colour point " << i << " minted no handle"; - EXPECT_TRUE(applied->Color[i].Res == expected) << "colour point " << i << " did not reach the server's record"; - EXPECT_EQ(applied->Color[i].Kind, kMGPipeSurfaceKindTexture) << "at colour point " << i; + EXPECT_FALSE(MGPipeHandleIsNull(expected)) << "color point " << i << " minted no handle"; + EXPECT_TRUE(applied->Color[i].Res == expected) << "color point " << i << " did not reach the server's record"; + EXPECT_EQ(applied->Color[i].Kind, kMGPipeSurfaceKindTexture) << "at color point " << i; } EXPECT_EQ(applied->Depth.Kind, kMGPipeSurfaceKindRenderbuffer) << "the Depth point"; EXPECT_EQ(applied->Stencil.Kind, kMGPipeSurfaceKindRenderbuffer) << "the Stencil point"; @@ -634,7 +634,7 @@ TEST(FramebufferEmit, TheRecordsElevenSurfacesAreTheWholePointSetTheServerReads) // (ClientSession's surface-changed consumer -> TextureObjectBase::PipePublishLevelDescriptor -> // MGP_NOTE_AGGREGATE(FramebufferAttachment) -> the framebuffer shutter) and told fb to pin it. // -// THE CASE DRIVES THE CONSUMER'S OWN CALL, not a synthetic bump: AllocateStorage on the colour +// THE CASE DRIVES THE CONSUMER'S OWN CALL, not a synthetic bump: AllocateStorage on the color // attachment at the new extent is literally what ClientSession does when the swapchain // publishes a new size. No rebind, no re-attach, no draw-buffer edit - which is exactly the // shape that would have been suppressed. @@ -696,8 +696,8 @@ TEST(FramebufferEmit, TheDefaultFramebuffersRecordNamesNoSurfaceAShareGroupWould ASSERT_NE(applied, nullptr) << "the default framebuffer's record did not reach the applier"; EXPECT_EQ(applied->IsDefault, 1) << "MGPFramebufferState::IsDefault"; for (Uint i = 0; i < kMGPipeMaxColorAttachments; ++i) { - EXPECT_EQ(applied->Color[i].Kind, kMGPipeSurfaceKindNone) << "MGPSurface::Kind at colour point " << i; - EXPECT_TRUE(MGPipeHandleIsNull(applied->Color[i].Res)) << "MGPSurface::Res at colour point " << i; + EXPECT_EQ(applied->Color[i].Kind, kMGPipeSurfaceKindNone) << "MGPSurface::Kind at color point " << i; + EXPECT_TRUE(MGPipeHandleIsNull(applied->Color[i].Res)) << "MGPSurface::Res at color point " << i; } EXPECT_EQ(applied->Depth.Kind, kMGPipeSurfaceKindNone) << "MGPSurface::Kind on the depth point"; EXPECT_EQ(applied->Stencil.Kind, kMGPipeSurfaceKindNone) << "MGPSurface::Kind on the stencil point"; @@ -836,7 +836,7 @@ TEST(FramebufferEmit, ADrawBufferTokenAboveTheWireWidthIsRefusedNotTruncated) { static_cast(kMGPipeMaxColorAttachments) + 2)); Framebuffers().EmitFramebufferState(Ctx()); EXPECT_EQ(Framebuffers().EmissionCount(), 1u) - << "a draw-buffer token naming a colour point at or above the wire width was truncated " + << "a draw-buffer token naming a color point at or above the wire width was truncated " "into a record instead of refused"; EXPECT_GE(Framebuffers().RefusedCount(), 1u) << "the refusal was not counted"; } @@ -882,7 +882,7 @@ TEST(FramebufferEmit, EveryNonTexturePointCarriesTheUnknownSentinelsRatherThanZe Framebuffers().EmitFramebufferState(Ctx()); const MGPFramebufferState& record = Framebuffers().LastDraw(); - // The RENDERBUFFER point, the EMPTY colour points and the STENCIL point that names nothing. + // The RENDERBUFFER point, the EMPTY color points and the STENCIL point that names nothing. for (const MGPSurface* surface : {&record.Depth, &record.Stencil, &record.Color[1]}) { EXPECT_NE(surface->Kind, kMGPipeSurfaceKindTexture); EXPECT_EQ(surface->UploadTarget, static_cast(TextureUploadTarget::Unknown)) @@ -1001,7 +1001,7 @@ TEST(FramebufferEmit, ATargetOutsideTheThreeBindingsIsRefusedNamingTheRecord) { } // The draw-buffer array is an INDEX into this record's own Color[], and -1 is NONE. An entry -// outside that range would have the server read a colour attachment the record does not carry, +// outside that range would have the server read a color attachment the record does not carry, // which is the truncation the wire width's cap refusal exists to prevent upstream. TEST(FramebufferEmit, ADrawBufferEntryOutsideTheRecordsOwnArrayIsRefusedRatherThanRead) { ApplierGuard guard; @@ -1018,13 +1018,13 @@ TEST(FramebufferEmit, ADrawBufferEntryOutsideTheRecordsOwnArrayIsRefusedRatherTh MGPFramebufferState past = FramebufferRecord(MGPipeHandle{8, 1}, MGPipeFramebufferTarget::Draw, 111); past.DrawBuffers[3] = static_cast(kMGPipeMaxColorAttachments); ExpectRefusedNaming("set_framebuffer_state {slot=8, gen=1, target=0}: a draw-buffer entry names a " - "colour attachment outside the record's own array", + "color attachment outside the record's own array", [&past]() { MGPipeApplySetFramebufferState(past); }); MGPFramebufferState negative = FramebufferRecord(MGPipeHandle{8, 1}, MGPipeFramebufferTarget::Draw, 222); negative.DrawBuffers[0] = -2; ExpectRefusedNaming("set_framebuffer_state {slot=8, gen=1, target=0}: a draw-buffer entry names a " - "colour attachment outside the record's own array", + "color attachment outside the record's own array", [&negative]() { MGPipeApplySetFramebufferState(negative); }); ASSERT_NE(MGPipeApplier().DrawFramebuffer(), nullptr); @@ -1179,7 +1179,7 @@ TEST(FramebufferEmit, ANamedRecordDescribesTheFramebufferItNamesWithoutMovingEit // never destroyed on the wire, so its slot is simply overwritten by its successor - and until // that successor describes itself, a handle naming the DEAD one must be refused rather than // answered with the predecessor's attachments. That answer would be a blit or a clear into -// somebody else's colour buffer. It is LOUD (counted, and logged once) because the only way to +// somebody else's color buffer. It is LOUD (counted, and logged once) because the only way to // reach it is an emitter defect, and it is counted APART from RefusedObjectCalls because this is // a read by the server's own sync path and not a call the applier refused. TEST(FramebufferEmit, AFramebufferHandleWhoseGenerationHasMovedOnIsRefusedRatherThanAnswered) { diff --git a/MobileGL/MG_Test/Pipe/ImageEmitTest.cpp b/MobileGL/MG_Test/Pipe/ImageEmitTest.cpp index 800fd042..f382dc0f 100644 --- a/MobileGL/MG_Test/Pipe/ImageEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/ImageEmitTest.cpp @@ -12,7 +12,7 @@ // WHAT THIS SUITE IS FOR. The image set is the one whose ContentHash has to cover more than // the binding: InternalFormat and Access are live glBindImageTexture state that the // format-less image bake keys on, so a set whose only movement is an access mode still has to -// go out. And the zero early-out is the property an optimisation deletes by accident - it is +// go out. And the zero early-out is the property an optimization deletes by accident - it is // what makes every draw of every application that never binds an image pay one integer test. // // THE SUITE IS `ImageEmit`, not `ImageEmitTest`: the file is XTest.cpp and the suite is X. @@ -372,7 +372,7 @@ namespace { return name; } - // PROPERTY 1 OF D-G4, and it is the one an optimisation deletes: an application that never + // PROPERTY 1 OF D-G4, and it is the one an optimization deletes: an application that never // binds an image pays one integer test per draw, taken BEFORE any hash and before any // 192-entry walk. // diff --git a/MobileGL/MG_Test/Pipe/PipeCatalogueTest.cpp b/MobileGL/MG_Test/Pipe/PipeCatalogueTest.cpp index 58017af4..efb83548 100644 --- a/MobileGL/MG_Test/Pipe/PipeCatalogueTest.cpp +++ b/MobileGL/MG_Test/Pipe/PipeCatalogueTest.cpp @@ -6,7 +6,7 @@ // SPDX-License-Identifier: LGPL-3.0-only // End of Source File Header -// The arithmetic of the MGPipe catalogue (plan B section 4.4, appendix A). Everything here +// The arithmetic of the MGPipe catalog (plan B section 4.4, appendix A). Everything here // is cheap on purpose: it is the test that fails when PipeCalls.def and the seven generated // files stop agreeing, and it must not need a GL context to say so. @@ -23,7 +23,7 @@ #include "Includes.h" #include -// P4a: MGPipeUnmigratedEmulation's declaration, and the applier's records the catalogue's size +// P4a: MGPipeUnmigratedEmulation's declaration, and the applier's records the catalog's size // pins now reach. Push-only, like the translation unit that defines them - in a pull build the // symbol does not exist and the one case that calls it is compiled out. #include @@ -61,7 +61,7 @@ TEST(PipeCatalogue, FrontendNeverTakesAnApplierAddress) { } namespace { - // Counting expansions of the catalogue. The Class parameter is a real enumerator, so a + // Counting expansions of the catalog. The Class parameter is a real enumerator, so a // per-class count is a constant expression too. #define MGP_COUNT_ONE(Name, Payload, Class, Flags, Wait) +1 #define MGP_COUNT_CLASS(Name, Payload, Class, Flags, Wait) +((Class) == countedClass ? 1 : 0) @@ -73,7 +73,7 @@ namespace { return 0 MGP_CALL_LIST(MGP_COUNT_CLASS); } - // Every payload named in the catalogue must be a memcpy-able POD, and so must every + // Every payload named in the catalog must be a memcpy-able POD, and so must every // payload the verify comparator knows about. #define MGP_ASSERT_CALL_PAYLOAD_POD(Name, Payload, Class, Flags, Wait) \ static_assert(std::is_trivially_copyable_v, #Name "'s payload " #Payload " is not trivially copyable"); @@ -83,9 +83,9 @@ namespace { static_assert(std::is_trivially_copyable_v, #Payload " is not trivially copyable"); MGP_VERIFY_PAYLOAD_LIST(MGP_ASSERT_VERIFY_PAYLOAD_POD) - // The catalogue's own spelling of an opcode, for a failure message. The wire codec has one + // The catalog's own spelling of an opcode, for a failure message. The wire codec has one // of these and MG_Pipe may not reach it (MG_Remote is above this layer), so the table is - // expanded from the catalogue here rather than a name being duplicated per EXPECT. + // expanded from the catalog here rather than a name being duplicated per EXPECT. #define MGP_CATALOGUE_NAME_ROW(Name, Payload, Class, Flags, Wait) #Name, constexpr const char* kCatalogueOpNames[] = {"", MGP_CALL_LIST(MGP_CATALOGUE_NAME_ROW)}; #undef MGP_CATALOGUE_NAME_ROW @@ -114,7 +114,7 @@ TEST(PipeCatalogue, HandleIsEightBytes) { EXPECT_FALSE(MGPipeIsCompositeShaderSlot(kMGPipeShaderCsoSlotLimit)); } -// The catalogue, the number documented in its header, and the two generated tables are one +// The catalog, the number documented in its header, and the two generated tables are one // fact stated three times. This is the test that notices when they stop being. TEST(PipeCatalogue, EntryCountMatchesTheDocumentedCount) { static_assert(kExpandedCallCount == MGP_CALL_LIST_DOCUMENTED_COUNT); @@ -201,7 +201,7 @@ TEST(PipeCatalogue, UninstalledTablesAreAllNull) { EXPECT_EQ(gMGPipeScreen.FenceCreate, nullptr); EXPECT_EQ(gMGPipeScreen.ApplierReset, nullptr); EXPECT_EQ(gMGPipeContext.ObjectDeath, nullptr); - // P5e's opcode 80 joins them: the row is catalogued, its codec layout is written and its + // P5e's opcode 80 joins them: the row is cataloged, its codec layout is written and its // tails are validated, but there is no MGPipeApplySetProgramBindings and no route - package // pg installs both. A null here is the contract, not an omission. EXPECT_EQ(gMGPipeContext.SetProgramBindings, nullptr); @@ -218,7 +218,7 @@ TEST(PipeCatalogue, ExactlyTheRoutedRowsAreInstalledAndTheRestAreStillNull) { // IDEMPOTENT, and called here on purpose: what this case observes is WHICH rows the // installer fills, not whether an installer ran somewhere in this binary. Leaving that to // ambient linkage is what made the same assertion pass in one build directory and fail in - // another - the object file carrying a static initialiser was dropped by the linker in the + // another - the object file carrying a static initializer was dropped by the linker in the // binaries that did not name a symbol in it. MGPipeInstallMonolithTables(); @@ -290,7 +290,7 @@ TEST(PipeCatalogue, ExactlyTheRoutedRowsAreInstalledAndTheRestAreStillNull) { // notice's mailbox are the producers, byte for byte as before (G1/G2). EXPECT_EQ(gMGPipeScreen.ApplierReset, nullptr); EXPECT_EQ(gMGPipeContext.ObjectDeath, nullptr); - // P5e's set_program_bindings (CONTRACT-P5E.md §1): catalogued with a null route until pg + // P5e's set_program_bindings (CONTRACT-P5E.md §1): cataloged with a null route until pg // installs the applier entry point and the adapter beside it. EXPECT_EQ(gMGPipeContext.SetProgramBindings, nullptr); } @@ -384,7 +384,7 @@ TEST(PipeCatalogue, TextureParamsNameTheirBuiltinSamplerAndFramebufferStateNames // the enum is the only thing that says what fits. EXPECT_LE(static_cast(MGPipeFramebufferTarget::Count), 256u); EXPECT_EQ(sizeof(MGPFramebufferState::Target), 1u); - // The wire's colour-attachment width is ONE width, and it is the wire's rather than the + // The wire's color-attachment width is ONE width, and it is the wire's rather than the // driver's: a driver reporting more attachments than this is refused at bring-up, never // truncated into the record. EXPECT_EQ(kMGPipeMaxColorAttachments, 8u); @@ -410,12 +410,12 @@ TEST(PipeCatalogue, EveryTextureTargetMapsToItsOwnResourceTarget) { << "TextureTarget " << i << " has no MGPResourceDesc::Target row"; EXPECT_LT(MGPipeResourceTargetForTextureTarget(target), static_cast(MGPipeResourceTarget::Count)); } - // Buffer is 0 and stays 0: P3a's constant is what a zero-initialised record already says, + // Buffer is 0 and stays 0: P3a's constant is what a zero-initialized record already says, // and the narrowed ack predicate below compares against it. EXPECT_EQ(static_cast(MGPipeResourceTarget::Buffer), 0u); EXPECT_EQ(kMGPipeResourceTargetBuffer, 0u); // No texture target may collide with the buffer target, or a texture descriptor would ask - // for a synchronous acknowledgement. + // for a synchronous acknowledgment. for (SizeT i = 0; i < static_cast(TextureTarget::TextureTargetCount); ++i) { EXPECT_NE(MGPipeResourceTargetForTextureTarget(static_cast(i)), static_cast(kMGPipeResourceTargetBuffer)); @@ -512,7 +512,7 @@ TEST(PipeCatalogue, SurfaceNamesItsKindItsTextureTargetAndItsDepthStencilAspect) EXPECT_EQ(kMGPipeSurfaceKindTexture, static_cast(MGPipeKind::Texture)); EXPECT_EQ(kMGPipeSurfaceKindRenderbuffer, static_cast(MGPipeKind::Renderbuffer)); EXPECT_NE(kMGPipeSurfaceKindTexture, kMGPipeSurfaceKindRenderbuffer); - // None == 0 is load-bearing: it is what makes a zero-initialised record already BE the + // None == 0 is load-bearing: it is what makes a zero-initialized record already BE the // empty attachment point, which every emitter and every reader relies on. EXPECT_EQ(kMGPipeSurfaceKindNone, 0u); @@ -611,7 +611,7 @@ TEST(PipeCatalogue, LateArrivalsAreAppendedWithoutRenumbering) { // P5e (§1) appended ONE more, by the same rule: opcode 80, and // nothing before it moved. set_program_bindings is a kCtxState row with THREE tails and a // host span in the third; it lands with a null route and a sink that refuses it by name, - // exactly as set_shader_buffers has sat catalogued-and-dead since P4a. + // exactly as set_shader_buffers has sat cataloged-and-dead since P4a. EXPECT_EQ(static_cast(MGPWireOp::SetProgramBindings), 80); EXPECT_EQ(static_cast(MGPWireOp::DeleteStreamOutput), 81); // P9 (§1) appended the two pack-buffer readbacks, by the same rule: @@ -824,7 +824,7 @@ TEST(PipeCatalogue, EveryRowCarriesTheWaitClassTheContractGivesIt) { } // The partition, by count. 15 + 1 + 1 = 17 rows wait (shared_image made the reply rows 15; P15 - // left one kWaitApplied row); every other row of the catalogue does + // left one kWaitApplied row); every other row of the catalog does // not. A row that changed class moves two of these numbers at once - which is why the // kWaitApplied count went 9 -> 10 and the kWaitNone offset 24 -> 25 in the SAME commit that // moved resource_copy_region (P5e gl, ID-118). @@ -854,8 +854,8 @@ TEST(PipeCatalogue, EveryRowCarriesTheWaitClassTheContractGivesIt) { EXPECT_EQ(none, static_cast(kMGPipeCallCount) - 17u); EXPECT_EQ(other, 0u) << "a row carries the kWaitClassCount terminator as its class"; - // And the reply half of the partition BOTH WAYS, over the whole catalogue: exactly the rows - // that own a slot wait for one. gen_pipe.py refuses a catalogue where they disagree; this + // And the reply half of the partition BOTH WAYS, over the whole catalog: exactly the rows + // that own a slot wait for one. gen_pipe.py refuses a catalog where they disagree; this // is the same statement where a reader of the table will look for it. for (SizeT i = 1; i < static_cast(MGPWireOp::kOpCount); ++i) { const auto op = static_cast(i); @@ -1016,7 +1016,7 @@ TEST(PipeCatalogue, FloatVectorsCompareBitwise) { EXPECT_FALSE(MGPipeVerify(leftState, rightState, &inner)); EXPECT_STREQ(inner, "BlendStates"); // P2's three new capability bools are members like any other, so the comparator names - // them rather than folding them into a neighbour's padding. + // them rather than folding them into a neighbor's padding. rightState = leftState; rightState.FramebufferSrgbEnabled = true; EXPECT_FALSE(MGPipeVerify(leftState, rightState, &inner)); @@ -1390,7 +1390,7 @@ TEST(PipeCatalogue, ResourceRespecifyAcksOnlyImmutableStorage) { // started acknowledging every immutable texture allocation the moment P4a's texture family // landed. Texture allocation is already deferred to sync time in monolith (glTexImage* and // glTexStorage* only mark the storage dirty, and even glRenderbufferStorage* allocates - // lazily inside SyncToBackend), so splitting changes no observable behaviour and this batch + // lazily inside SyncToBackend), so splitting changes no observable behavior and this batch // must not ack. glBufferStorage stays the only entry point allowed a synchronous one. // // This is the negative control for a future widening, in both directions: a predicate that @@ -1411,13 +1411,13 @@ TEST(PipeCatalogue, ResourceRespecifyAcksOnlyImmutableStorage) { EXPECT_FALSE(MGPipeResourceRespecifyNeedsAck(renderbuffer)); // And the buffer half still answers true with the target spelled explicitly rather than - // relying on a zero-initialised record to mean "buffer". + // relying on a zero-initialized record to mean "buffer". MGPResourceDesc immutableBuffer{}; immutableBuffer.Immutable = 1; immutableBuffer.Target = kMGPipeResourceTargetBuffer; EXPECT_TRUE(MGPipeResourceRespecifyNeedsAck(immutableBuffer)); - // And the opcode did not move: a flag-word edit is not a catalogue edit. + // And the opcode did not move: a flag-word edit is not a catalog edit. EXPECT_EQ(static_cast(MGPWireOp::ResourceRespecify), 3); // P4a, ID-18 M4. The metadata-update rule is a PROSE contract stated beside the predicate @@ -1436,7 +1436,7 @@ TEST(PipeCatalogue, ResourceRespecifyAcksOnlyImmutableStorage) { EXPECT_NE(offsetof(MGPResourceDesc, HasDefinedContent), offsetof(MGPResourceDesc, ImageBindableHint)); } -// G13b, D-M: "emulation 在 split 下显式 Fatal 直到 P8" costs P4a a NAMED, GREPPABLE call site +// G13b, D-M: "emulations are an explicit Fatal under split until P8" costs P4a a NAMED, GREPPABLE call site // per unmigrated emulation and nothing else - in monolith MGPipeUnmigratedEmulation is a no-op // and the emulation still runs on exactly the code path it runs on today. What this pins is // the LIST, because the whole value of the mechanism is that P5 and P8 edit one function diff --git a/MobileGL/MG_Test/Pipe/PipeInputsTest.cpp b/MobileGL/MG_Test/Pipe/PipeInputsTest.cpp index 24283e0a..ffef5007 100644 --- a/MobileGL/MG_Test/Pipe/PipeInputsTest.cpp +++ b/MobileGL/MG_Test/Pipe/PipeInputsTest.cpp @@ -76,9 +76,7 @@ namespace { m_previous = MG_State::pGLContext.Take(); MG_State::pGLContext = MakeUnique(); } - void TearDown() override { - MG_State::pGLContext = Move(m_previous); - } + void TearDown() override { MG_State::pGLContext = Move(m_previous); } SharedPtr m_previous; }; @@ -250,7 +248,7 @@ TEST_F(PipeInputsTest, ReadingAFilledFieldCompletes) { // The window before the first verb (P1 brief D6: "@"). Nothing has filled this // process's block, so a backend-style read of a value field is Fatal naming no verb: the // serial and every stamp are 0, and 0 == 0 is not fresh. In a verify build the child also -// sets the lane's knob first, the shape of a read reached from initialisation: the poison +// sets the lane's knob first, the shape of a read reached from initialization: the poison // fires at MGP_INPUT_CHECK, before the read hook (armed only by the first fill) could matter. TEST_F(PipeInputsTest, ReadingBeforeAnyFillAbortsNamingNoVerb) { #if !MOBILEGL_PIPE_POISON diff --git a/MobileGL/MG_Test/Pipe/ProgramEmitTest.cpp b/MobileGL/MG_Test/Pipe/ProgramEmitTest.cpp index 97c5f167..e873b89a 100644 --- a/MobileGL/MG_Test/Pipe/ProgramEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/ProgramEmitTest.cpp @@ -62,7 +62,7 @@ #include #include #include -// The applier takes the two artefact structs BY POINTER beside the record, so a case that +// The applier takes the two artifact structs BY POINTER beside the record, so a case that // drives create_shader_state needs their definitions - the applier's own header deliberately // only forward-declares them. #include @@ -217,7 +217,7 @@ namespace { desc.PointSizeDemoted = 1; desc.EnableSpirvValidation = 1; // ALL SEVEN BLOB REFS ARE DECLARED WITH Size 0 - "this record does not declare its - // blob" - which is exactly what a monolith emission is: the artefacts ride beside the + // blob" - which is exactly what a monolith emission is: the artifacts ride beside the // record through the two companion pointers and the codec is never called. return desc; } @@ -283,7 +283,7 @@ TEST(ProgramEmit, ACreateStoresTheDescriptorAndARelinkCountsUpAndDropsTheBlockKe EXPECT_EQ(ProgramRecordOf(5).Desc.StageMask, 0x1u); } -// The three refusals a create can produce: no artefacts at all behind seven undeclared blobs, a +// The three refusals a create can produce: no artifacts at all behind seven undeclared blobs, a // default uniform block no program can have, and a slot outside the record table's bound. TEST(ProgramEmit, ACreateWithNoArtefactsAnOversizedBlockOrACorruptSlotIsRefusedNamingTheProgram) { ApplierGuard guard; @@ -292,10 +292,10 @@ TEST(ProgramEmit, ACreateWithNoArtefactsAnOversizedBlockOrACorruptSlotIsRefusedN const MGPProgramDesc desc = ProgramDesc(MGPipeHandle{4, 1}, 0x3u, 0); ExpectRefusedNaming("create_shader_state {slot=4, gen=1}: the record declares no blobs and carries no " - "artefacts", + "artifacts", [&desc, &spirv]() { MGPipeApplyCreateShaderState(desc, nullptr, &spirv, nullptr); }); ExpectRefusedNaming("create_shader_state {slot=4, gen=1}: the record declares no blobs and carries no " - "artefacts", + "artifacts", [&desc, &link]() { MGPipeApplyCreateShaderState(desc, &link, nullptr, nullptr); }); EXPECT_TRUE(MGPipeApplier().ShaderCsos.empty()); @@ -568,7 +568,7 @@ void main() { gl_Position = vec4(0.0); EmitVertex(); } // PINNED AS A PREDICATE rather than by driving the counter to ~0u, and the reason is // written down instead of hidden: reaching that value takes four billion // MarkUBOContentDirty calls, which is not a test. The predicate is the thing - // EmitGlobalConstants consults, so pinning it pins the behaviour, and a deletion of the + // EmitGlobalConstants consults, so pinning it pins the behavior, and a deletion of the // guard is a compile error here. TEST(ProgramEmit, TheNeverUploadedSentinelIsNeverEmitted) { EmitterScope scope; @@ -1050,7 +1050,7 @@ void main() { gl_Position = u_a + u_b + u_c + u_d; } "the frontend reports unlinked"; EXPECT_EQ(Emitter().LastProgramDesc().LinkStatus, 0u) << "the re-issue claims the program linked"; EXPECT_TRUE(MGPipeSlots().IsLive(MGPipeKind::ShaderCso, cso)) - << "a failed relink must never be modelled as an object_death"; + << "a failed relink must never be modeled as an object_death"; } // The frame, both ways round. SpirvArtifacts carries no stage list and MGPProgramDesc:: diff --git a/MobileGL/MG_Test/Pipe/RecorderGoldenTest.cpp b/MobileGL/MG_Test/Pipe/RecorderGoldenTest.cpp index 3e521059..4b922575 100644 --- a/MobileGL/MG_Test/Pipe/RecorderGoldenTest.cpp +++ b/MobileGL/MG_Test/Pipe/RecorderGoldenTest.cpp @@ -18,7 +18,7 @@ // * the verb session (MG_Record::SetVerbSessionResolver), i.e. every verb record the emitters // in MG_Impl/Pipe/Verb plan - the same bytes a transport would carry. // -// Each record is NORMALISED (the one thing in a payload that is not a function of the GL calls is +// Each record is NORMALIZED (the one thing in a payload that is not a function of the GL calls is // an address: an MGPBlobRef / MGHostSpan naming caller memory - zeroed, the size kept; the bytes // they name are hashed instead) and hashed with its companion bytes and tails. The golden is one // line per record - index, call name, size, hash - in goldens/recorder/.txt, small enough @@ -100,7 +100,7 @@ namespace { g_stream->push_back(Record{op, bytes, hash.Value}); } - // ---- normalisation: addresses out, sizes kept -------------------------------------------------- + // ---- normalization: addresses out, sizes kept -------------------------------------------------- void Scrub(MGPBlobRef& blob) { if (blob.Seg == kMGHostSpanSegNone) blob.Offset = 0; @@ -210,7 +210,7 @@ namespace { return HashRest(hash, op, blob, blobBytes) + HashRest(hash, op, tail, count); } - // ---- the table wrappers, one per catalogue row ------------------------------------------------- + // ---- the table wrappers, one per catalog row ------------------------------------------------- template struct Wrap; diff --git a/MobileGL/MG_Test/Pipe/RenderStateSpansTest.cpp b/MobileGL/MG_Test/Pipe/RenderStateSpansTest.cpp index b42b7342..3a3f7d48 100644 --- a/MobileGL/MG_Test/Pipe/RenderStateSpansTest.cpp +++ b/MobileGL/MG_Test/Pipe/RenderStateSpansTest.cpp @@ -165,7 +165,7 @@ namespace { EXPECT_EQ(gotSrcA, wantSrcA) << "blend func " << i; EXPECT_EQ(gotDstA, wantDstA) << "blend func " << i; - EXPECT_EQ(gPipeInputs->GetColorMaskIndexed(i), ctx.GetColorMaskIndexed(i)) << "colour mask " << i; + EXPECT_EQ(gPipeInputs->GetColorMaskIndexed(i), ctx.GetColorMaskIndexed(i)) << "color mask " << i; EXPECT_EQ(gPipeInputs->IsCapabilityEnabledIndexed(CapabilityInput::Blend, i), ctx.IsCapabilityEnabledIndexed(CapabilityInput::Blend, i)) << "indexed blend enable " << i; @@ -503,7 +503,7 @@ namespace { StencilOperation::IncrementWrap); }); - // ---- Colour mask, clear state, sampling ---- + // ---- Color mask, clear state, sampling ---- check("SetColorMask", [](RenderState& s) { s.SetColorMask(BoolVec4(true, false, true, false)); }); check("SetColorMaskIndexed", [](RenderState& s) { s.SetColorMaskIndexed(6, BoolVec4(false, false, true, true)); }); @@ -867,7 +867,7 @@ namespace { BlendFactor::SrcAlpha); ctx.SetBlendEquationIndexed(5, BlendEquation::ReverseSubtract, BlendEquation::Max); ctx.SetColorMaskIndexed(0, BoolVec4(false, true, false, true)); - push("step 3: blend and colour mask (pipeline chunk P1)"); + push("step 3: blend and color mask (pipeline chunk P1)"); ctx.SetCapabilityIndexed(CapabilityInput::Blend, 0, true); push("step 4: indexed blend enable at index 0"); diff --git a/MobileGL/MG_Test/Pipe/ResourceEmitTest.cpp b/MobileGL/MG_Test/Pipe/ResourceEmitTest.cpp index 55a193ba..c6878f59 100644 --- a/MobileGL/MG_Test/Pipe/ResourceEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/ResourceEmitTest.cpp @@ -503,7 +503,7 @@ namespace { EXPECT_TRUE(MGPipeSetSubDataBufferRange(record, 0, 0xFFFFFFFFull)); } - // BEHAVIOUR NEUTRALITY, ASSERTED RATHER THAN ASSUMED. Every dispatch in the family is a + // BEHAVIOR NEUTRALITY, ASSERTED RATHER THAN ASSUMED. Every dispatch in the family is a // null check that falls through while no backend has installed a table - which is what // lets the client half land without changing a single observable - and every one of them // hands the backend a HANDLE and a payload, never a frontend object. @@ -1456,9 +1456,9 @@ namespace { // The slot spaces of kinds Buffer, Texture and Renderbuffer are independent - the client // allocator is per kind - so one slot-indexed table would alias three live objects onto one // record. These cases are about the branch and nothing else: which table a call lands in, - // that the three do not see each other, and that a target or a kind the catalogue does not + // that the three do not see each other, and that a target or a kind the catalog does not // name is refused rather than routed to whichever table came first. The texture family's - // own behaviour (parameters, the sub-data validator, the pending-upload set) is in + // own behavior (parameters, the sub-data validator, the pending-upload set) is in // TextureEmitTest beside the emitter cases it belongs with. // ===================================================================================== @@ -1699,7 +1699,7 @@ namespace { } // Neither branch may fall through to a table it was not named. A target or a kind outside - // the catalogue would otherwise land in whichever table the code happened to reach first, + // the catalog would otherwise land in whichever table the code happened to reach first, // and destroy a live object of a kind the call was never about. TEST(ResourceEmit, AResourceTargetOrKindTheCatalogueDoesNotNameIsRefusedRatherThanRouted) { ApplierGuard guard; @@ -1896,7 +1896,7 @@ namespace { // // Every enumerator, one fresh buffer each, so the assertion is an EQUALITY rather than a // "has the bit": a target that maps to no bit at all (the transfer and query targets) - // must leave the mask empty, and a table row that leaked a neighbour's bit fails here. + // must leave the mask empty, and a table row that leaked a neighbor's bit fails here. // // ON CREATE the mask is necessarily empty and that is not a gap in the test: the create // is emitted from the buffer object's CONSTRUCTOR, and nothing can be bound to an object @@ -2171,7 +2171,7 @@ namespace { EXPECT_EQ(covered, whole) << "the split covered the range more or less than exactly once"; }; - // Three chunks and a remainder: the smallest range that says the cap is being honoured + // Three chunks and a remainder: the smallest range that says the cap is being honored // rather than the record's own bound - and at that bound the same range is ONE record, // so what cuts it below is the stage chunk and nothing else. constexpr Uint64 kThreeChunks = kChunk * 3 + 7; diff --git a/MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp b/MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp index 4e7431b7..2d6c8f05 100644 --- a/MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/SamplerEmitTest.cpp @@ -11,13 +11,13 @@ // // THIS SUITE IS A NAMED GATE (`ctest -R 'SamplerEmit\.'`), and its negative control is a // script that stops the conversion copying SamplerParameters::borderColorForm and expects this -// suite to go red NAMING that field - which it must, because all three border-colour +// suite to go red NAMING that field - which it must, because all three border-color // representations are always numerically populated and the value alone cannot say which driver // entry point to use. // // THE ONE CASE THAT LOOKS LIKE PARANOIA AND IS NOT: SamplerParameters is 100 bytes with THREE // BYTES OF TRAILING PADDING, so a cache that hashes or memcmps the object's own bytes reads -// uninitialised memory and mints a fresh CSO per call - a 256-entry cache with a hit rate of +// uninitialized memory and mints a fresh CSO per call - a 256-entry cache with a hit rate of // zero, and nobody notices, because the pixels are right. The case that writes garbage into // the padding through a byte pointer is what turns that into a red gate. // @@ -202,7 +202,7 @@ TEST(SamplerEmit, TheEmitterIsOneNeverDestroyedProcessSingleton) { // ========================================================================================= // The APPLIER's half of the sampler family (the wire commits'): the CSO record, the // identity-addressed view record and its back-pointer, and the two unit sets. The emitter's -// half - the content-addressed 256-entry cache, the canonical zero-initialised copy the hash +// half - the content-addressed 256-entry cache, the canonical zero-initialized copy the hash // and the memcmp run over, the padding that cannot change the hash, borderColorForm crossing - // is the client package's and lands beside these. // ========================================================================================= @@ -531,7 +531,7 @@ namespace { // gtest refuses to mix TEST and TEST_F under one suite name. // // UNLIKE VertexInputEmitTest's, this scope does NOT replace pGLContext: half these cases - // need a really linked program, so the process is initialised once in main() and the cases + // need a really linked program, so the process is initialized once in main() and the cases // share that context, each using GL names of its own. What the scope does is put the // emitter, its counters and the suppressor back to a known state. struct EmitterScope { @@ -660,7 +660,7 @@ namespace { Uint64 payload = 0; const MGPipeHandle first = Cache().Acquire(clean, payload); const MGPipeHandle second = Cache().Acquire(dirty, payload); - EXPECT_EQ(first, second) << "uninitialised padding must not mint a second CSO"; + EXPECT_EQ(first, second) << "uninitialized padding must not mint a second CSO"; EXPECT_EQ(Cache().GetCounters().Mints, 1u); EXPECT_EQ(Cache().GetCounters().Hits, 1u); } @@ -689,7 +689,7 @@ namespace { params.borderColorForm = BorderColorForm::Uint; const MGPipeHandle asUint = Cache().Acquire(params, payload); EXPECT_NE(asInt, asUint) << "the form is the only thing that says which driver entry " - "point applies; the three colour values did not move"; + "point applies; the three color values did not move"; EXPECT_EQ(Cache().GetCounters().Mints, 2u); } diff --git a/MobileGL/MG_Test/Pipe/ShaderBufferEmitTest.cpp b/MobileGL/MG_Test/Pipe/ShaderBufferEmitTest.cpp index 0bd53adb..b29310ab 100644 --- a/MobileGL/MG_Test/Pipe/ShaderBufferEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/ShaderBufferEmitTest.cpp @@ -10,7 +10,7 @@ // (§5.6, rulings 10 and 11; package sb). // // WHAT THIS SUITE IS FOR. Three properties of this family are invisible in a picture and are -// exactly what an optimisation or a merge deletes: +// exactly what an optimization or a merge deletes: // 1. the ZERO EARLY-OUT - a class nothing has bound emits nothing, before any hash; // 2. a BASE binding travels as kMGPipeWholeBuffer and never as a resolved extent, so a // glBufferData between the emission and the apply binds the NEW extent as GL does; diff --git a/MobileGL/MG_Test/Pipe/TextureEmitTest.cpp b/MobileGL/MG_Test/Pipe/TextureEmitTest.cpp index 86ef101f..f75acacb 100644 --- a/MobileGL/MG_Test/Pipe/TextureEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/TextureEmitTest.cpp @@ -2213,7 +2213,7 @@ TEST(TextureEmit, ARespecifyOfOneLevelKeepsThePendingUploadsOfTheOthers) { EXPECT_EQ(TextureRecordOf(10).PendingUploads[1].UploadTarget, secondFace); // And the key it DOES name goes, because that level's coordinate system has been replaced. - // The redefinition modelled here is glTexImage2D(level 1) with a NEW internal format - a + // The redefinition modeled here is glTexImage2D(level 1) with a NEW internal format - a // legal thing to do to a mutable texture, and a real redefinition of that level's storage, // so the descriptor moves and the metadata arm does not claim it. ASSERT_TRUE(MGPipeApplyResourceSubData(TextureUpload(texture, 1, MGPBox{0, 0, 0, 32, 32, 1}, 0), texels)); @@ -2393,7 +2393,7 @@ TEST(TextureEmit, ASubDataRecordWhoseResourceTargetNamesNoTextureIsRefusedRather "to upload into", [&renderbuffer, &texels]() { MGPipeApplyResourceSubData(renderbuffer, texels); }); - // And so is a value at or above the catalogue, and so is the buffer target arriving with a + // And so is a value at or above the catalog, and so is the buffer target arriving with a // non-zero upload-target half - which the whole-field buffer test above cannot see. MGPSubData pastTheCatalogue = renderbuffer; pastTheCatalogue.Target = static_cast(MGPipeResourceTarget::Count); @@ -2479,7 +2479,7 @@ TEST(TextureEmit, ARespecifyThatRedefinesNoStorageCarriesTheStickyMaskAndKeepsTh masked.BindMask = static_cast(allocated.BindMask | kMGPipeBindShaderImage); masked.ImageBindableHint = 1; ASSERT_FALSE(MGPipeResourceRespecifyNeedsAck(masked)) - << "a metadata respecify must never ask for a reallocation acknowledgement"; + << "a metadata respecify must never ask for a reallocation acknowledgment"; ASSERT_TRUE(MGPipeApplyResourceRespecify(masked, nullptr)); EXPECT_EQ(TextureRecordOf(11).Desc.BindMask, masked.BindMask) diff --git a/MobileGL/MG_Test/Pipe/TrackerTest.cpp b/MobileGL/MG_Test/Pipe/TrackerTest.cpp index 0d6c9402..763b13d0 100644 --- a/MobileGL/MG_Test/Pipe/TrackerTest.cpp +++ b/MobileGL/MG_Test/Pipe/TrackerTest.cpp @@ -1209,7 +1209,7 @@ namespace { ASSERT_EQ(MGPipeVertexAttribDefaultsLastHeader().Count, 1u) << "a steady context published more than the one attribute that moved"; - // A different context, whose 32 defaults are the value-initialised {0,0,0,1} the + // A different context, whose 32 defaults are the value-initialized {0,0,0,1} the // tracker's own reset produces - so a diff against the staging mirror finds nothing. MG_State::pGLContext = MakeUnique(); Draw(); diff --git a/MobileGL/MG_Test/Pipe/VertexInputEmitTest.cpp b/MobileGL/MG_Test/Pipe/VertexInputEmitTest.cpp index 3ecf257c..beebb4cf 100644 --- a/MobileGL/MG_Test/Pipe/VertexInputEmitTest.cpp +++ b/MobileGL/MG_Test/Pipe/VertexInputEmitTest.cpp @@ -673,7 +673,7 @@ namespace { constexpr int kChurn = 64; Uint32 peakLive = 0; for (int round = 0; round < kChurn; ++round) { - // Through the name allocator, so MarkVertexArrayForDeletion recognises the name and + // Through the name allocator, so MarkVertexArrayForDeletion recognizes the name and // actually drops the slot's reference - and so the recycled NAME is part of the // shape, exactly as a chunk renderer's is. The lifetime id is fresh every round // whatever the name does, which is what the free has to key on. diff --git a/MobileGL/MG_Test/Pipeline/PassthroughTessControlTest.cpp b/MobileGL/MG_Test/Pipeline/PassthroughTessControlTest.cpp index 467b044a..64cfd0cc 100644 --- a/MobileGL/MG_Test/Pipeline/PassthroughTessControlTest.cpp +++ b/MobileGL/MG_Test/Pipeline/PassthroughTessControlTest.cpp @@ -63,7 +63,7 @@ namespace { // The built-in members of every block in the module, keyed by the struct's result id, in // member order. A gl_PerVertex is exactly such a struct, and its member list IS the shape the - // neighbouring stage has to agree with. + // neighboring stage has to agree with. constexpr Uint32 kOpTypeStruct = 30; std::map> BuiltInBlockShapes(const Vector& spirv) { @@ -212,7 +212,7 @@ TEST_F(PassthroughTessControlTest, CompilesWithNonDefaultLevels) { EXPECT_TRUE(shaderResult) << (shaderResult ? String{} : shaderResult.error().log) << source; } -// The generator honours the mask it is given, in both directions. This is what covers the +// The generator honors the mask it is given, in both directions. This is what covers the // pre-cutoff three-member form now that no authorable tessellation evaluation stage produces it // (ARB_tessellation_shader is GL 4.0 and gl_CullDistance joins the block at 400), and it is also // the fallback ReflectPassthroughTessControlNeed uses when it cannot read a module's block. @@ -253,7 +253,7 @@ TEST_F(PassthroughTessControlTest, RedeclaresExactlyTheRequestedMembers) { TEST_F(PassthroughTessControlTest, MatchesTheFrontendPerVertexBlock) { using namespace MG_Util::ShaderTranspiler; - // MORE THAN ONE VERSION, because the shape is a function of the neighbour's GLSL version and + // MORE THAN ONE VERSION, because the shape is a function of the neighbor's GLSL version and // a single-version case cannot see that. glslang gates gl_PerVertex's gl_CullDistance member // on a version cutoff, and this case used to link #version 430 ONLY - which is exactly why a // generator hardcoded to the pre-cutoff three-member form looked correct while every program diff --git a/MobileGL/MG_Test/Pipeline/PipelineQuirkTest.cpp b/MobileGL/MG_Test/Pipeline/PipelineQuirkTest.cpp index 04cf6bbe..abf9392c 100644 --- a/MobileGL/MG_Test/Pipeline/PipelineQuirkTest.cpp +++ b/MobileGL/MG_Test/Pipeline/PipelineQuirkTest.cpp @@ -663,7 +663,7 @@ TEST(PipelineQuirkTest, WireDepthResolveProbeKnobReplacesTheMeasurementNotTheVer EXPECT_FALSE(clean.preferShader); EXPECT_EQ(measured, 0) << "a forced verdict must not also run the device probe"; const auto other = ChooseWireDepthResolveArm(WireDepthResolveProbeKnob::Unrecognised, true, measure); - EXPECT_EQ(measured, 1) << "an unrecognised value runs the probe as if the knob were unset"; + EXPECT_EQ(measured, 1) << "an unrecognized value runs the probe as if the knob were unset"; EXPECT_FALSE(other.measurement.fromKnob); EXPECT_EQ(other.verdict, WireDepthResolveProbeVerdict::Clean); // `elide-subject` is the REAL probe's negative control: it decides nothing here - the device @@ -856,11 +856,11 @@ TEST(PipelineQuirkTest, WirePlaceholderKeysArePrivatePerShapeAndUnitAndBounded) } // P7 g3-blit (g3det, ~/w7/logs/g3det/VERDICT.md section 3): WHICH SAMPLER THE WIRE ARM'S SHADER -// COLOUR BLIT USES (WireColorBlitFilter.h). GL filters only a STRETCHED blit, so a 1:1 blit is a copy +// COLOR BLIT USES (WireColorBlitFilter.h). GL filters only a STRETCHED blit, so a 1:1 blit is a copy // whatever `filter` says. The wire pass sampled every GL_LINEAR blit through its linear sampler; on // Adreno 830 the sub-texel coordinate quantisation moved create-instancing's 1:1 GL_LINEAR blit into // FB 0 by 1 LSB on 712 edge pixels, while the monolith's vkCmdBlitImage copied them exactly. -// Lavapipe samples texel centres exactly and shows the same picture on both samplers, so no host +// Lavapipe samples texel centers exactly and shows the same picture on both samplers, so no host // lane can see this; the choice is pinned here instead. // // Red once (executed, reverted): WireColorBlitFilterFor reduced to the old mapping @@ -902,7 +902,7 @@ TEST(PipelineQuirkTest, WireColorBlitSamplesNearestWhereTheBlitIsACopy) { }; for (const auto& copy : copies) { EXPECT_TRUE(WireBlitIsUnscaled(copy.source, copy.destination)) << copy.what; - // A quarter turn maps logical pixel centres onto native ones (the native extent is the + // A quarter turn maps logical pixel centers onto native ones (the native extent is the // logical one swapped), so a copy is still a copy on every rotated surface. for (const auto transform : kExpressedTransforms) { EXPECT_EQ(WireColorBlitFilterFor(copy.source, copy.destination, GL_LINEAR, transform), VK_FILTER_NEAREST) diff --git a/MobileGL/MG_Test/Program/AsyncSpirvPhaseTest.cpp b/MobileGL/MG_Test/Program/AsyncSpirvPhaseTest.cpp index b7296381..845ebb96 100644 --- a/MobileGL/MG_Test/Program/AsyncSpirvPhaseTest.cpp +++ b/MobileGL/MG_Test/Program/AsyncSpirvPhaseTest.cpp @@ -330,9 +330,9 @@ void main() { fragColor = vec4(1.0); } // --------------------------------------------------------------------------------------- // The state the split invented and GL gives no way out of: phase A published LINK_STATUS -// GL_TRUE, and phase B then settled CANCELLED rather than Complete - its body threw +// GL_TRUE, and phase B then settled CANCELED rather than Complete - its body threw // (bad_alloc out of GlslangToSpv/spirv-opt under pack-load memory pressure), the pool failed -// to enqueue it, or teardown cancelled it while it was queued. The shadow is then a +// to enqueue it, or teardown canceled it while it was queued. The shadow is then a // default-constructed SpirvArtifacts: empty uniformOffsets, null scratch, spirvStatus false - // while the whole phase-A query surface, IsValidUniformLocation() included, keeps answering. // @@ -366,7 +366,7 @@ TEST_F(AsyncSpirvPhaseTest, ALinkedProgramWhoseSpirvJobWasCancelledDegradesInste ++cancelled; // ---- the contract: linked, fully queryable, not drawable ---- - EXPECT_TRUE(object->GetLinkStatus()) << "a cancelled phase B must not retract LINK_STATUS"; + EXPECT_TRUE(object->GetLinkStatus()) << "a canceled phase B must not retract LINK_STATUS"; EXPECT_EQ(QueryLinkStatus(program), GL_TRUE); EXPECT_FALSE(object->GetSpirvStatus()); EXPECT_TRUE(object->IsSpirvComplete()); @@ -420,7 +420,7 @@ TEST_F(AsyncSpirvPhaseTest, ALinkedProgramWhoseSpirvJobWasCancelledDegradesInste EXPECT_EQ(GetError(), GL_NO_ERROR); } - EXPECT_GT(cancelled, 0) << "no phase B was ever cancelled; this case proved nothing"; + EXPECT_GT(cancelled, 0) << "no phase B was ever canceled; this case proved nothing"; } // The mirror image: with async off the state is not reachable at all, because both bodies run @@ -791,7 +791,7 @@ TEST_F(AsyncSpirvPhaseTest, RelinkingOverAPendingSpirvJobIsClean) { GetUniformfv(program, secondTint, tint); for (int c = 0; c < 3; ++c) { EXPECT_FLOAT_EQ(tint[c], 0.0f) - << "a uniform write buffered against the cancelled link leaked into the relink, component " << c; + << "a uniform write buffered against the canceled link leaked into the relink, component " << c; } } diff --git a/MobileGL/MG_Test/Program/AsyncTeardownTest.cpp b/MobileGL/MG_Test/Program/AsyncTeardownTest.cpp index 42094738..646e342f 100644 --- a/MobileGL/MG_Test/Program/AsyncTeardownTest.cpp +++ b/MobileGL/MG_Test/Program/AsyncTeardownTest.cpp @@ -110,7 +110,7 @@ TEST(AsyncTeardown, DestroyWithCompilesAndLinksInFlight) { MobileGL::Destroy(); // Back up again. The pool stays stopped for the rest of the process (a one-way latch), so - // this second life is synchronous - which is exactly the documented behaviour, and it has + // this second life is synchronous - which is exactly the documented behavior, and it has // to still be a WORKING one. MobileGL::Initialize(); const GLuint vs2 = MakeShader(GL_VERTEX_SHADER, kVs); diff --git a/MobileGL/MG_Test/Program/OptimisticStatusTest.cpp b/MobileGL/MG_Test/Program/OptimisticStatusTest.cpp index 4bf42854..dba2991d 100644 --- a/MobileGL/MG_Test/Program/OptimisticStatusTest.cpp +++ b/MobileGL/MG_Test/Program/OptimisticStatusTest.cpp @@ -327,7 +327,7 @@ void main() { fragColor = thisIdentifierWasNeverDeclared; } // With the quirk unset (Auto = the shipped default), GL_COMPILE_STATUS on a pending compile // must join it: after the query, the node is terminal. This is the case that guards the // default against ever silently flipping. No blocker here - a blocked pool would turn the -// (correct) joining behaviour into a deadlock; a plain backlog only makes the pre-join +// (correct) joining behavior into a deadlock; a plain backlog only makes the pre-join // state likely, and the assertion is valid either way. TEST_F(OptimisticStatusTest, OffByDefaultTheStatusStillJoins) { const AsyncModeScope async(true); diff --git a/MobileGL/MG_Test/Program/ParallelShaderCompileTest.cpp b/MobileGL/MG_Test/Program/ParallelShaderCompileTest.cpp index 7beaa746..8da9c8d6 100644 --- a/MobileGL/MG_Test/Program/ParallelShaderCompileTest.cpp +++ b/MobileGL/MG_Test/Program/ParallelShaderCompileTest.cpp @@ -16,7 +16,7 @@ // * GL_MAX_SHADER_COMPILER_THREADS_KHR; // * the extension string itself, which must appear if and only if asynchronous // compilation is enabled - the kill switch has to revert the application-visible -// behaviour change, not only the threading. +// behavior change, not only the threading. // // Like the other async suites, every case drives the real GL entry points and flips // MG_Config::Features.AsyncShaderCompile itself, so the file behaves identically whether or diff --git a/MobileGL/MG_Test/Program/ProgramInterfaceTest.cpp b/MobileGL/MG_Test/Program/ProgramInterfaceTest.cpp index 3b383faa..91ffcab2 100644 --- a/MobileGL/MG_Test/Program/ProgramInterfaceTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramInterfaceTest.cpp @@ -1974,7 +1974,7 @@ void main() { color = u + v; } // ------------------------------------------------------------- length on every path ---- // glGetProgramResourceiv's *length is the caller's only signal for how many entries params - // holds, and callers are entitled to leave it uninitialised: the CTS declares `GLsizei + // holds, and callers are entitled to leave it uninitialized: the CTS declares `GLsizei // length;` next to a 1000-entry stack array and then loops `for (i = 0; i < length; ++i)` // (gl4cProgramInterfaceQueryTests.cpp:2172). Leaving it untouched on an error path therefore // does not "return nothing" - it hands the caller whatever was on its stack and makes it walk diff --git a/MobileGL/MG_Test/Program/ProgramTest.cpp b/MobileGL/MG_Test/Program/ProgramTest.cpp index 4893a0af..a0c75c57 100644 --- a/MobileGL/MG_Test/Program/ProgramTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramTest.cpp @@ -428,7 +428,7 @@ void main() { // // THE REFERENCE IS COMPUTED HERE, not copied as a constant, and it is computed with the same // algorithm the old consumer used: per module in linked-stage order, STORAGE_BUFFER -// descriptors only, sorted by (normalised name, binding), deduplicated across modules by name. +// descriptors only, sorted by (normalized name, binding), deduplicated across modules by name. // Comparing against a hand-written expected list would only pin what the author believed. // // THE PROGRAM IS THE ONE THE CONTRACT ASKS FOR: multi-stage (vertex + fragment), with an @@ -605,7 +605,7 @@ void main() { // The arrayed block must appear ONCE, under its stripped name: glslang reflects it per // element and SPIR-V carries one descriptor, and collapsing the two is the whole reason - // the archive normalises. + // the archive normalizes. EXPECT_EQ(std::count(archived.begin(), archived.end(), String("Blocks")), 1) << "the arrayed SSBO must collapse to one entry named without its subscript"; // The atomic counter is in the BACKEND's space even though GL's own enumeration excludes it. @@ -2866,7 +2866,7 @@ TEST_F(ProgramTest, UniformBlockListExcludesStorageAndAtomicCounterBlocks) { GetActiveUniformBlockiv(program, blk2, GL_UNIFORM_BLOCK_BINDING, &binding); EXPECT_EQ(binding, 7); GetActiveUniformBlockiv(program, blk, GL_UNIFORM_BLOCK_BINDING, &binding); - EXPECT_NE(binding, 7) << "the rebind must not have leaked onto the neighbouring block"; + EXPECT_NE(binding, 7) << "the rebind must not have leaked onto the neighboring block"; EXPECT_EQ(GetError(), GL_NO_ERROR); // An index past the end of the (now shorter) list is GL_INVALID_VALUE, not a silently @@ -3679,11 +3679,11 @@ TEST_F(ProgramTest, TwoShaderObjectsWithIdenticalSourceLinkIndependently) { // single parse - made safe by ClaimParsedShader's CAS, exactly as it already was for // one shader object attached to two programs. ShaderCompileAdoptionTest pins that // down by linking both objects and comparing the generated SPIR-V. - // * The translation memo's compile half (L1c) recognises the second object's source and + // * The translation memo's compile half (L1c) recognizes the second object's source and // publishes its verdict WITHOUT parsing, so that object legitimately holds no TShader // at all until a link asks ClaimParsedShader for one. Asserting a non-null parse here // would be asserting that the parse had NOT been skipped - i.e. testing the absence - // of the optimisation rather than the invariant. + // of the optimization rather than the invariant. // // So the pointer assertion applies only where the two objects are genuinely INDEPENDENT, // i.e. where job adoption is not in play. What every mode has to agree on is the two @@ -3694,7 +3694,7 @@ TEST_F(ProgramTest, TwoShaderObjectsWithIdenticalSourceLinkIndependently) { // Either may legitimately hold NO parse: that is an L1c hit, where the AST is made on // demand at link instead. So this asserts they are not the SAME non-null parse, and // deliberately not that both have one - the latter would be asserting that the - // optimisation had not happened. + // optimization had not happened. if (shaderA != nullptr && shaderB != nullptr) { EXPECT_NE(shaderA, shaderB) << "two independent shader objects share one consume-once parse"; } @@ -3771,7 +3771,7 @@ TEST_F(ProgramTest, PreprocessCacheOverflowKeepsCompilingCorrectly) { // glUniformMatrix{2x3,2x4,3x2,3x4,4x2,4x3}fv and their twelve glProgramUniformMatrix* twins were // validate-only no-ops: they never took the value pointer at all. They upload column-at-a-time at -// the std140 16-byte column stride, honouring `transpose`, and glGetUniformfv undoes that padding. +// the std140 16-byte column stride, honoring `transpose`, and glGetUniformfv undoes that padding. TEST_F(ProgramTest, NonSquareMatrixUniformsRoundTripThroughTheGlobalUbo) { const char* vsSource = R"(#version 430 core uniform mat2x3 uM2x3; @@ -3889,7 +3889,7 @@ void main() { fragColor = vec4(1.0); } EXPECT_EQ(GetError(), GL_NO_ERROR); } -// GL 4.6 core 7.1: shaderType is an enum, so an unrecognised one is INVALID_ENUM - it used to be +// GL 4.6 core 7.1: shaderType is an enum, so an unrecognized one is INVALID_ENUM - it used to be // reported as INVALID_VALUE. glCreateShaderProgramv adds a count < 0 gate ahead of everything. TEST_F(ProgramTest, CreateShaderAndCreateShaderProgramvReportTheRightErrorClasses) { while (GetError() != GL_NO_ERROR) {} @@ -4366,10 +4366,10 @@ void main() { mgColor = vec4(1.0); } )"; } // namespace -// Two fragment outputs on ONE location with DIFFERENT colour indices is not an aliasing error - +// Two fragment outputs on ONE location with DIFFERENT color indices is not an aliasing error - // it is dual-source blending (GL 4.6 core 11.1.3 / ARB_blend_func_extended, core since 3.3), and // the GL_SRC1_* blend factors have nothing to read without it. The link-time aliasing check keyed -// on the colour number alone, so every such program failed to link with "alias color number 0" +// on the color number alone, so every such program failed to link with "alias color number 0" // and the whole feature was unreachable from shader-side GLSL. TEST_F(ProgramTest, FragmentOutputsMayShareALocationWhenTheirColorIndexDiffers) { constexpr const char* dualSourceFs = R"(#version 460 core @@ -4385,7 +4385,7 @@ void main() { fragColor0 = vec4(1.0); fragColor1 = vec4(0.5); } GetProgramInfoLog(program, sizeof(log), nullptr, log); return std::string(log); }(); - // Both outputs are active and both sit on colour number 0 - which is the shape that used to be + // Both outputs are active and both sit on color number 0 - which is the shape that used to be // refused. (glGetFragDataIndex still answers 0 for the index-1 output: it reports only what // glBindFragDataLocationIndexed bound, and reflecting the shader-side qualifier is a separate // gap, so it is deliberately not asserted here.) @@ -4394,7 +4394,7 @@ void main() { fragColor0 = vec4(1.0); fragColor1 = vec4(0.5); } EXPECT_EQ(GetError(), GL_NO_ERROR); } -// The check it must NOT stop making: two outputs on the same colour number AND the same index +// The check it must NOT stop making: two outputs on the same color number AND the same index // really do alias, and that link has to fail. Aliased through glBindFragDataLocation rather than // through two `layout(location = 0)` qualifiers on purpose - the qualifier form is caught by // glslang at COMPILE time, so it would never reach the link-time rule this pins. @@ -4426,7 +4426,7 @@ void main() { fragColorA = vec4(1.0); fragColorB = vec4(0.5); } GetProgramInfoLog(program, sizeof(infoLog), nullptr, infoLog); EXPECT_NE(std::string(infoLog).find("alias color number"), std::string::npos) << infoLog; - // ...and the same pair separated by the colour INDEX links, which is the whole point of the + // ...and the same pair separated by the color INDEX links, which is the whole point of the // key being a pair. BindFragDataLocationIndexed(program, 0, 1, "fragColorB"); LinkProgram(program); @@ -4439,7 +4439,7 @@ void main() { fragColorA = vec4(1.0); fragColorB = vec4(0.5); } for (int i = 0; i < 32 && GetError() != GL_NO_ERROR; ++i) {} } -// An API colour index of ZERO is "no override", not "index 0". glBindFragDataLocation is +// An API color index of ZERO is "no override", not "index 0". glBindFragDataLocation is // glBindFragDataLocationIndexed with index 0 (GL_Program.cpp), so the blanket-bind pattern - // portable code that binds every output name it knows about, without caring about dual-source - // writes a real 0 into the frag-data index map for an output whose shader qualifier says 1. @@ -4468,7 +4468,7 @@ void main() { fragColor0 = vec4(1.0); fragColor1 = vec4(0.5); } AttachShader(program, fs); DeleteShader(fs); - // The blanket bind: colour number 0, index 0, on the output the shader put at index 1. + // The blanket bind: color number 0, index 0, on the output the shader put at index 1. BindFragDataLocation(program, 0, "fragColor0"); BindFragDataLocation(program, 0, "fragColor1"); LinkProgram(program); diff --git a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp index 212f9889..f3b71015 100644 --- a/MobileGL/MG_Test/Program/ProgramUtilTest.cpp +++ b/MobileGL/MG_Test/Program/ProgramUtilTest.cpp @@ -665,7 +665,7 @@ void main() { // declaration, so measure the line rather than assuming its length. EXPECT_EQ(outputPos, source.find('\n', versionPos) + 1); EXPECT_NE(source.find("// #version 460 core"), String::npos); - // This #line sits ahead of the version directive, where GLSL would never have honoured it, so + // This #line sits ahead of the version directive, where GLSL would never have honored it, so // it is still dropped. Directives that follow the version line are kept - see // PreprocessKeepsPlainLineDirectivesAndSparesLookalikeIdentifiers. EXPECT_EQ(source.find("#line"), String::npos); @@ -995,7 +995,7 @@ void main() { TEST_F(ProgramUtilTest, RetargetLegacyVersionDirectiveOnlyTouchesNormalizedDesktopCore) { using namespace MG_Util::ShaderTranspiler; - // Only MobileGL's own normalization is retargetable, and it is recognised by the marker the + // Only MobileGL's own normalization is retargetable, and it is recognized by the marker the // preprocessor leaves on the directive line - so normalize a legacy source rather than // hand-writing the directive the marker belongs to. String normalized = "#version 130\nvoid main() {}\n"; @@ -2386,7 +2386,7 @@ TEST_F(ProgramUtilTest, CompileEnvWithoutBackendAdvertisesEverything) { EXPECT_TRUE(env.IsExtensionAdvertised(MobileGL::E_GL_ARB_gpu_shader_int64)); } -// P0b layer 2: ShaderPreprocessCache, tested directly. The GL-level behaviour it +// P0b layer 2: ShaderPreprocessCache, tested directly. The GL-level behavior it // enables is covered end to end in ProgramTest; these pin the container itself, // where the interesting cases (hash collisions, both eviction budgets) are hard // to provoke through glCompileShader. @@ -3350,7 +3350,7 @@ void main() { const Vector spirv = BuildSpirvForStage(vs, GL_VERTEX_SHADER); ASSERT_FALSE(spirv.empty()); EXPECT_TRUE(ShaderCompiler::ModuleDeclaresBufferTextureSampler(spirv)) - << "an isamplerBuffer must be recognised as a buffer texture"; + << "an isamplerBuffer must be recognized as a buffer texture"; } // The float and unsigned spellings lower to the same Dim=Buffer image with a different @@ -3396,7 +3396,7 @@ void main() { fragColor = texture(Albedo, vUv) + vec4(texelFetch(Ids, ivec2(0), << "only Dim=Buffer images are buffer textures"; } -// Pins the SPIRV-Cross behaviour the whole defect rests on: below ESSL 320 it synthesizes an +// Pins the SPIRV-Cross behavior the whole defect rests on: below ESSL 320 it synthesizes an // EXT_texture_buffer requirement from the image type itself. There is nothing in the module // to strip - which is why the OES driver is served by retargeting the emitted directive // (RetargetTextureBufferExtension) rather than by rewriting the SPIR-V. @@ -3501,7 +3501,7 @@ void main() { ssb.sum = imageAtomicAdd(i0, 2, 7u); } // The negative control, and the whole reason the pass exists: SPIRV-Cross's ES emulation of 1D // images does not ask whether the type is arrayed, so it wraps an already-two-component -// coordinate in a two-component constructor. Pinning the upstream behaviour here means that if a +// coordinate in a two-component constructor. Pinning the upstream behavior here means that if a // future SPIRV-Cross bump fixes it, this test fails and says so, rather than the pass quietly // becoming dead weight. TEST_F(ProgramUtilTest, SpirvCrossEmitsAMalformedCoordinateFor1DArrayImages) { @@ -3638,7 +3638,7 @@ void main() { ssb.sum = imageLoad(i0, 2).r; } // all: SPIRV-Cross widens a 1D image coordinate in OpImageRead and OpImageWrite but not in // OpImageTexelPointer, so the atomic comes out addressing an `uimage2D` with a scalar. Every ES // driver answers "no matching overloaded function found" and the whole stage - with every other -// image in it - is lost. Pinning the upstream behaviour here means a future SPIRV-Cross bump that +// image in it - is lost. Pinning the upstream behavior here means a future SPIRV-Cross bump that // fixes it fails this test instead of leaving the lowering as silent dead weight. TEST_F(ProgramUtilTest, SpirvCrossEmitsAScalarCoordinateForA1DImageAtomic) { using namespace MG_Util::ShaderTranspiler; @@ -3805,7 +3805,7 @@ void main() { ssb.data = textureLodOffset(g_sampler4, vec2(0.5, 1.0), 0.0, 0); } // The negative control, and the whole reason the pass exists: SPIRV-Cross emits the sampler as 2D // and widens the coordinate, then hands the scalar offset straight through. Pinning the upstream -// behaviour here means that if a future SPIRV-Cross bump fixes it, this test fails and says so, +// behavior here means that if a future SPIRV-Cross bump fixes it, this test fails and says so, // rather than the pass quietly becoming dead weight. TEST_F(ProgramUtilTest, SpirvCrossEmitsAScalarOffsetFor1DSamplers) { using namespace MG_Util::ShaderTranspiler; diff --git a/MobileGL/MG_Test/Program/ShaderCompileAdoptionTest.cpp b/MobileGL/MG_Test/Program/ShaderCompileAdoptionTest.cpp index 3a44089e..17d64a54 100644 --- a/MobileGL/MG_Test/Program/ShaderCompileAdoptionTest.cpp +++ b/MobileGL/MG_Test/Program/ShaderCompileAdoptionTest.cpp @@ -13,7 +13,7 @@ // two programs linking that one node to byte-identical SPIR-V; // * that sharing did not make a cancel dangerous. Before this stage a node had exactly one // shader object, so "this object stopped caring" and "nothing can observe this result" -// were the same statement and CancelCompile() cancelled unconditionally. They are not the +// were the same statement and CancelCompile() canceled unconditionally. They are not the // same statement any more, and the four mutation paths that used to reach that cancel - // re-source, delete, the orphan-name sweep, the destructor - are each covered below with // a second object still holding the node. @@ -453,9 +453,9 @@ TEST_F(ShaderCompileAdoptionTest, DeletingOneSharerLeavesTheOtherIntact) { // RunBody() for it - when the last holder releases it. ReleaseCompileNode fires Cancel(), // but JobNode::Cancel on a Running node only sets the cancellation-REQUEST flag; the state // stays Running until the worker's body returns and JobNode::Run forces the final transition -// to Cancelled (see JobNode::Run's tail: it takes Cancelled instead of Complete whenever +// to Canceled (see JobNode::Run's tail: it takes Canceled instead of Complete whenever // m_cancelled is set, regardless of how the body finished). FindAdoptable must refuse a node -// in that in-between state - not just one already settled as Cancelled - or C inherits a +// in that in-between state - not just one already settled as Canceled - or C inherits a // doomed node and glGetShaderiv reports GL_FALSE with an empty info log for valid source. TEST_F(ShaderCompileAdoptionTest, RunningCancelRequestedNodeIsNotAdopted) { const AsyncModeScope async(true); @@ -584,7 +584,7 @@ TEST_F(ShaderCompileAdoptionTest, OrphanSweepWithALinkPinnedSharedNodeHoldsBoth) } // Every sharer released, in turn, with nothing pinning the node: the LAST release is the one -// that may cancel, and afterwards the map must not hand the cancelled node to anybody. The +// that may cancel, and afterwards the map must not hand the canceled node to anybody. The // property asserted is the one that matters and it is timing-free: whatever happened to the // old node, a later object with the same source must end up with a CORRECT compile. TEST_F(ShaderCompileAdoptionTest, AfterEverySharerIsGoneTheNextCompileIsStillCorrect) { @@ -613,7 +613,7 @@ TEST_F(ShaderCompileAdoptionTest, AfterEverySharerIsGoneTheNextCompileIsStillCor ShaderSource(c, 1, &text, nullptr); CompileShader(c); ASSERT_EQ(QueryCompileStatus(c), GL_TRUE) - << "a cancelled node must never be adopted - it can only ever report GL_FALSE. " << QueryShaderInfoLog(c); + << "a canceled node must never be adopted - it can only ever report GL_FALSE. " << QueryShaderInfoLog(c); const GLuint program = LinkWith(c); ASSERT_EQ(QueryLinkStatus(program), GL_TRUE); EXPECT_GE(GetUniformLocation(program, "uSeed240"), 0); @@ -621,7 +621,7 @@ TEST_F(ShaderCompileAdoptionTest, AfterEverySharerIsGoneTheNextCompileIsStillCor } // --------------------------------------------------------------------------------------- -// The bypasses: both must be byte-identical to the pre-stage-6 behaviour +// The bypasses: both must be byte-identical to the pre-stage-6 behavior // --------------------------------------------------------------------------------------- // The kill switch. With the flag off, compilation is synchronous and NOTHING is adopted - @@ -737,7 +737,7 @@ TEST_F(ShaderCompileAdoptionTest, StressFortyEightObjectsOverSixSources) { // The adversarial interleaving, with duplicates everywhere: compile, query, re-source, // re-compile, delete, all with the pool busy and most objects sharing nodes. Nothing here -// asserts timing - what it hunts for is a node cancelled out from under a sharer, which +// asserts timing - what it hunts for is a node canceled out from under a sharer, which // surfaces as a wrong status, a wrong uniform, or a crash. TEST_F(ShaderCompileAdoptionTest, StressSharedNodesUnderResourceAndDelete) { const AsyncModeScope async(true); @@ -796,7 +796,7 @@ TEST_F(ShaderCompileAdoptionTest, StressSharedNodesUnderResourceAndDelete) { // The map itself, driven directly // --------------------------------------------------------------------------------------- // Two of the map's rules cannot be forced deterministically through the GL surface - a -// cancelled node depends on beating a worker to it, and a CompileEnv re-capture needs a +// canceled node depends on beating a worker to it, and a CompileEnv re-capture needs a // backend swap. Both are unconditional properties of the class, so they are asserted here // against the class. @@ -853,7 +853,7 @@ TEST(ShaderCompileAdoptionMapTest, EnvFingerprintMismatchIsNotAdopted) { EXPECT_EQ(map.GetAdoptionCount(), 0u); } -// A node that settled as Cancelled published nothing, so adopting it would hand the new +// A node that settled as Canceled published nothing, so adopting it would hand the new // object a compile that can only ever report GL_FALSE. It must be a miss, and the dead entry // must be pruned where it is found rather than waiting for the amortized sweep. TEST(ShaderCompileAdoptionMapTest, CancelledNodeIsNotAdoptedAndIsPruned) { @@ -862,7 +862,7 @@ TEST(ShaderCompileAdoptionMapTest, CancelledNodeIsNotAdoptedAndIsPruned) { const String text = "#version 460\nvoid main() {}\n"; const SharedPtr node = MakeNode(text, ShaderStage::Fragment, env); map.Register(node); - // Never posted, so this settles the node as Cancelled right here. + // Never posted, so this settles the node as Canceled right here. node->Cancel(); ASSERT_TRUE(node->IsCancelled()); ASSERT_EQ(map.GetEntryCount(), 1u); diff --git a/MobileGL/MG_Test/SanityTest.cpp b/MobileGL/MG_Test/SanityTest.cpp index a6d1f52d..d1ddb06a 100644 --- a/MobileGL/MG_Test/SanityTest.cpp +++ b/MobileGL/MG_Test/SanityTest.cpp @@ -102,8 +102,8 @@ namespace { // ctest -R Sanity` is the legacy-arm run of the same binary and the A/B is one env var. // // It runs as a gtest Environment rather than a static initializer on purpose: - // MG_Config::Features has a String member, so it is dynamically initialised, and writing - // to it from another TU's static initializer would be an initialisation-order race. + // MG_Config::Features has a String member, so it is dynamically initialized, and writing + // to it from another TU's static initializer would be an initialization-order race. // SetUp() runs inside RUN_ALL_TESTS, long after every static initializer, and before the // first test - hence before anything can latch EsprytSlotTablesEnabled(). class EsprytSlotArmEnvironment final : public ::testing::Environment { @@ -542,7 +542,7 @@ TEST(DirectVulkanSanity, SampledViewAspectFollowsDepthStencilTextureMode) { static_cast(VK_IMAGE_ASPECT_DEPTH_BIT)); EXPECT_EQ(VkTextureManager::ResolveSampledImageViewAspectMask(kPacked, GL_STENCIL_INDEX), static_cast(VK_IMAGE_ASPECT_STENCIL_BIT)); - // The default argument is the pre-existing behaviour, for the call sites with no texture. + // The default argument is the pre-existing behavior, for the call sites with no texture. EXPECT_EQ(VkTextureManager::ResolveSampledImageViewAspectMask(kPacked), static_cast(VK_IMAGE_ASPECT_DEPTH_BIT)); @@ -1531,7 +1531,7 @@ TEST(GetterSanity, MaxElementIndexIsTheFull32BitIndexCeiling) { // GL 4.6 core table 23.53 gives GL_MAX_SAMPLES a minimum of four and the three per-category // ceilings a minimum of ONE. Flooring the latter at four is the advertised-caps lie that made // KHR-GL46.sample_variables.mask.rgba8i run at all: the frontend promised four integer samples, -// the backend clamped the realised allocation to the one the driver can back, and the application +// the backend clamped the realized allocation to the one the driver can back, and the application // wrote per-sample data it could never read. TEST(GetterSanity, PerCategoryMultisampleCeilingsAreProbedRatherThanFlooredAtFour) { using namespace MobileGL; @@ -2971,7 +2971,7 @@ TEST(DirectGLESStateGuards, DefaultFramebufferBindGoesThroughShadow) { // first mass eviction during world load - the failure FastSTL's double-advancing // erase actually produced before it was fixed). // -// These pin the behaviour the call sites rely on, not one map's implementation, so +// These pin the behavior the call sites rely on, not one map's implementation, so // they are written against MobileGL::UnorderedMap and survive changing what it // names. Under ska::flat_hash_map the mechanism is different - erase backward-shifts // the rest of the probe cluster into the hole and hands back the same slot, which @@ -3806,7 +3806,7 @@ TEST(DirectGLESSlotTable, EveryReKeyedObjectClassAnnouncesItsOwnDeath) { expected.emplace_back(MG_Pipe::MGPipeKind::VertexElementsCso, vertexArray->GetLifetimeId()); // P3a, and it is DELIBERATELY NOT in `expected`: the buffer is the seventh re-keyed - // class and the only one whose death does not travel on this notice. The catalogue + // class and the only one whose death does not travel on this notice. The catalog // has a call for it - resource_destroy - so no seventh NotifyStateObjectDestroyed // raiser was added (D-L). StateObjectDeathNotice.h exists for kinds that have NO // such call, and a buffer raising one too would be two death signals for one object, diff --git a/MobileGL/MG_Test/SelfTest/DriverBugProbesTest.cpp b/MobileGL/MG_Test/SelfTest/DriverBugProbesTest.cpp index c3554710..5e5c19bb 100644 --- a/MobileGL/MG_Test/SelfTest/DriverBugProbesTest.cpp +++ b/MobileGL/MG_Test/SelfTest/DriverBugProbesTest.cpp @@ -104,7 +104,7 @@ namespace { // Probe 5's inconclusive path: nothing compiles, including the location-0 control. bool everyCompileFails = false; // Probe 6: a blit writes the destination array layer the framebuffer names, or always - // layer 0. The second knob is the inconclusive path - a driver that does not honour the + // layer 0. The second knob is the inconclusive path - a driver that does not honor the // SOURCE layer either fails the probe's control. bool blitIgnoresDestinationLayer = false; bool blitIgnoresSourceLayer = false; @@ -112,7 +112,7 @@ namespace { // Probe 7: the driver stores a WHOLE 16-bit packed ALLOCATION with its fields packed // from the other end of the word - on the measured device, every level of the probe's // 30x30x12 three-level array, while same-shape plain-2D images stay in the canonical - // order. Modelled at the raw copy, which is the only path that can observe it (uploads + // order. Modeled at the raw copy, which is the only path that can observe it (uploads // and readbacks of the same image decode the driver's own layout consistently): a copy // whose SOURCE is any level of the mirrored allocation delivers the mirrored // re-encoding, which the plain-2D readback then decodes with the non-REV order - @@ -178,7 +178,7 @@ namespace { // The device rule the probe reproduces: the mirrored layout is only picked when // the levels were uploaded onto a texture still at the driver defaults - any // glTexParameteri BEFORE the first upload steers the driver to the plain layout. - // Modelling it makes a params-first probe (the round-one regression: it measured + // Modeling it makes a params-first probe (the round-one regression: it measured // "clean" in the very context whose params-after textures mirrored) stop // detecting, which turns that mistake into a red test instead of a silent miss. bool paramsTouchedBeforeUpload = false; @@ -639,7 +639,7 @@ namespace { g_fake.lastSampledValue = 0.0f; } else if (g_fake.msaaSwizzledAlphaCorrupted && swizzle == GL_RED && component == 'w' && sampleIndex != 0 && g_fake.sampledMultisampleProgramCount >= 2) { - // Uninitialised memory: a value that is neither the answer nor the clear. + // Uninitialized memory: a value that is neither the answer nor the clear. g_fake.lastSampledValue = -1.34954e-17f; } return; diff --git a/MobileGL/MG_Test/SelfTest/PrimitivesGeneratedNoXfbProbeTest.cpp b/MobileGL/MG_Test/SelfTest/PrimitivesGeneratedNoXfbProbeTest.cpp index 53e97c3b..3d76d9b2 100644 --- a/MobileGL/MG_Test/SelfTest/PrimitivesGeneratedNoXfbProbeTest.cpp +++ b/MobileGL/MG_Test/SelfTest/PrimitivesGeneratedNoXfbProbeTest.cpp @@ -11,7 +11,7 @@ // GPU; the two pure functions are where the cheap mistakes live - a verdict that reads a // half-broken driver as healthy, an override arm swapped so ForceOn disarms, a // substitute ranked below a worse one - and every driver the campaign has -// characterised is written down here as a fake measurement so the mapping cannot +// characterized is written down here as a fake measurement so the mapping cannot // drift without a red: // - a conforming driver (stream counts everywhere), // - lavapipe as measured 2026-08: stream silent everywhere, the dedicated diff --git a/MobileGL/MG_Test/ShaderTranspiler/ClampMultisampleFetchTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/ClampMultisampleFetchTest.cpp index cc5dc77a..35073aaa 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/ClampMultisampleFetchTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/ClampMultisampleFetchTest.cpp @@ -191,7 +191,7 @@ void main() { } )"; - // The colour class, which real devices squeeze to something above 1 rather than to 1. + // The color class, which real devices squeeze to something above 1 rather than to 1. const char* const kColorMultisampleFetch = R"(#version 410 core uniform sampler2DMS colorMs; out vec4 fragColor; @@ -268,7 +268,7 @@ TEST_F(ClampMultisampleFetchTest, TheCombinedProbeAgreesWithThePerGateOnes) { // The overwhelming majority of modules. Behind the probe they never reach the pass at all, but the // pass has to be inert for them on its own, or a future caller that forgets the gate silently -// re-serialises every shader in the program. +// re-serializes every shader in the program. TEST_F(ClampMultisampleFetchTest, LeavesAModuleWithoutAMultisampledImageUntouched) { const Vector input = CompileFragment(kNoMultisampleFetch); ASSERT_FALSE(input.empty()); @@ -328,7 +328,7 @@ TEST_F(ClampMultisampleFetchTest, ReplacesAnOutOfRangeIntegerSampleWithZero) { } // The same shader on a device whose integer ceiling really is what MobileGL advertises. Nothing is -// out of range, so nothing may be rewritten - and the module must not even be re-serialised. +// out of range, so nothing may be rewritten - and the module must not even be re-serialized. TEST_F(ClampMultisampleFetchTest, LeavesTheFetchAloneWhenTheCategoryReachesTheAdvertisedMaximum) { const Vector input = CompileFragment(kIntegerMultisampleFetch); ASSERT_FALSE(input.empty()); @@ -412,7 +412,7 @@ void main() { } } // namespace -// Integer colour squeezed to one sample but depth/stencil at four (Adreno): a usampler2DMS fetch +// Integer color squeezed to one sample but depth/stencil at four (Adreno): a usampler2DMS fetch // straight from its uniform is handed to the runtime bound and keeps sample 3 - a stencil texture // really has it - while the fetch through a parameter and the signed one still read sample 0. TEST_F(ClampMultisampleFetchTest, DefersADirectUnsignedFetchToTheRuntimeBound) { diff --git a/MobileGL/MG_Test/ShaderTranspiler/DemoteFloat64Test.cpp b/MobileGL/MG_Test/ShaderTranspiler/DemoteFloat64Test.cpp index 6a9e0cf0..aee227a5 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/DemoteFloat64Test.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/DemoteFloat64Test.cpp @@ -800,7 +800,7 @@ TEST_F(DemoteFloat64Test, TheThirtyTwoBitBehaviourIsUnchanged) { EXPECT_FALSE(RewritesToAnAbsoluteValueTest(CompareAgainst("float", "1.0"))) << "a float compared against 1.0 must not be rewritten"; EXPECT_TRUE(RewritesToAnAbsoluteValueTest(CompareAgainst("float", "0.0"))) - << "the 32-bit behaviour this pass shipped with must be preserved exactly"; + << "the 32-bit behavior this pass shipped with must be preserved exactly"; } // The pass matches ZERO, not "small". The old constant-is-zero test was `fabs(v) <= 1e-4`, so a diff --git a/MobileGL/MG_Test/ShaderTranspiler/ExtendNarrowIntegerVertexInputsRuntimeTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/ExtendNarrowIntegerVertexInputsRuntimeTest.cpp index cab1ad74..f64a0767 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/ExtendNarrowIntegerVertexInputsRuntimeTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/ExtendNarrowIntegerVertexInputsRuntimeTest.cpp @@ -169,7 +169,7 @@ TEST(ExtendNarrowIntegerVertexInputsRuntimeWidths, SeedsEveryIntegerInputFromThe EXPECT_EQ(ValidationError(output), String{}); const String text = Disassemble(output); - // The two globals: named, Private, initialised to 0 and never stored. + // The two globals: named, Private, initialized to 0 and never stored. for (const char* name : {kNarrowIntegerWidths8GlobalName, kNarrowIntegerWidths16GlobalName}) { const String id = String("%") + name; EXPECT_NE(text.find(id + " = OpVariable %_ptr_Private_uint Private %uint_0"), String::npos) << name << "\n" diff --git a/MobileGL/MG_Test/ShaderTranspiler/ExtendNarrowIntegerVertexInputsTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/ExtendNarrowIntegerVertexInputsTest.cpp index b13f05b4..fac3ac40 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/ExtendNarrowIntegerVertexInputsTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/ExtendNarrowIntegerVertexInputsTest.cpp @@ -227,7 +227,7 @@ TEST(ExtendNarrowIntegerVertexInputs, LeavesEverythingElseUnchanged) { } // From SPIR-V 1.4 an entry point lists every global it uses, so the Private copies have to join -// the new Inputs in the interface. Checked by re-labelling the module 1.4 and validating it for an +// the new Inputs in the interface. Checked by re-labeling the module 1.4 and validating it for an // environment that accepts 1.4. TEST(ExtendNarrowIntegerVertexInputs, ListsPrivateCopiesInASpirv14Interface) { MobileGL::Initialize(); diff --git a/MobileGL/MG_Test/ShaderTranspiler/FixIterationRPSubgroupScratchTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/FixIterationRPSubgroupScratchTest.cpp index 7a59bf88..14c07ba2 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/FixIterationRPSubgroupScratchTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/FixIterationRPSubgroupScratchTest.cpp @@ -252,7 +252,7 @@ TEST(FixIterationRPSubgroupScratchPass, GrowsTheExposureScratchForNarrowSubgroup ASSERT_EQ(WorkgroupArrayLengths(input), (std::vector{4u, 32u})); // lavapipe: 8-lane subgroups over 512 invocations need 64 entries; the - // plainly indexed neighbour must keep its 4. + // plainly indexed neighbor must keep its 4. Vector output; ASSERT_TRUE(ShaderCompiler::FixIterationRPSubgroupScratchForVulkan(input, output, 8u, 32768u, true)); EXPECT_EQ(WorkgroupArrayLengths(output), (std::vector{4u, 64u})); diff --git a/MobileGL/MG_Test/ShaderTranspiler/FlattenFloat64StorageBlockTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/FlattenFloat64StorageBlockTest.cpp index db05831e..4bae8031 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/FlattenFloat64StorageBlockTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/FlattenFloat64StorageBlockTest.cpp @@ -8,7 +8,7 @@ // // FlattenFloat64StorageBlockPass, over the module the production chain actually hands it: // ShaderCompiler::SanitizeAndOptimizeBinary, where the pass sits immediately before the fp64 -// demotion. The behavioural half - that a block copied through the flattened words comes back +// demotion. The behavioral half - that a block copied through the flattened words comes back // byte for byte - is DoublePrecisionScenario's; what only a module walk can say is WHICH blocks // were flattened, how wide, and that the ones this pass must not touch came through unchanged. @@ -401,7 +401,7 @@ TEST_F(FlattenFloat64StorageBlockTest, TheNativePathLeavesTheBlockAndItsDoublesA // And the control: the SAME module through the SAME entry point with the bit clear is flattened // exactly as it always was. This is the pair that pins "capability-false is byte-for-byte the old -// behaviour" at the level the device A/B checks. +// behavior" at the level the device A/B checks. TEST_F(FlattenFloat64StorageBlockTest, TheDemotedPathIsUnchangedByTheCapabilityArgument) { const Vector input = CompileToSpirv(GL_COMPUTE_SHADER, kStd140BlockSource); ASSERT_FALSE(input.empty()); diff --git a/MobileGL/MG_Test/ShaderTranspiler/GlslangCaptureTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/GlslangCaptureTest.cpp index 0b7a4261..f545d471 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/GlslangCaptureTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/GlslangCaptureTest.cpp @@ -352,7 +352,7 @@ void main() { gl_Position = vec4(two_d[1][2] + three_d[1][1][3] + one_d[2]); } EXPECT_EQ(locations.count("one_d[0]"), 0u); } -// A DELIBERATE BEHAVIOUR CHANGE, recorded here because it is the one place the migration does +// A DELIBERATE BEHAVIOR CHANGE, recorded here because it is the one place the migration does // not reproduce the old answer. // // The lexical extractor advanced the location across the declarators of one statement, so @@ -471,7 +471,7 @@ void main() { realBlock.u = atomicCounterIncrement(counterA) + atomicCounterIncr ASSERT_TRUE(capture.linked) << capture.log; EXPECT_EQ(capture.storageBlocksWithoutBinding.count("RealBlock"), 1u) - << "the application's own unqualified block is still recognised"; + << "the application's own unqualified block is still recognized"; for (const String& name : capture.storageBlocksWithoutBinding) { EXPECT_FALSE(name.starts_with(MG_Util::ShaderTranspiler::ATOMIC_COUNTER_BLOCK_PREFIX)) << "a synthesized atomic-counter block reached the storage-block capture: " << name; @@ -557,7 +557,7 @@ void main() { ASSERT_TRUE(capture.linked) << capture.log; EXPECT_EQ(capture.storageBlocksWithoutBinding.count("OutputBuffer"), 1u) - << "the block the test binds at 0 with glBindBufferBase must be recognised"; + << "the block the test binds at 0 with glBindBufferBase must be recognized"; EXPECT_EQ(capture.storageBlocksWithoutBinding.count("BoundBlock"), 0u) << "a declared binding must never be defaulted away"; EXPECT_EQ(capture.storageBlocksWithoutBinding.count("BoundFirst"), 0u) @@ -683,7 +683,7 @@ void main() { EXPECT_EQ(capture.storageBlocksWithoutBinding.count("PlainLayout"), 1u) << "std430/row_major are layout identifiers, not bindings"; EXPECT_EQ(capture.storageBlocksWithoutBinding.count("ReallyUnqualified"), 1u) - << "a block that truly declares no binding is still recognised in the same shader"; + << "a block that truly declares no binding is still recognized in the same shader"; } // THE NEGATIVE CONTROL for the storage-block capture. @@ -714,8 +714,8 @@ void main() { gl_Position = vec4(float(sharedInstance.u + vertexOnly.v)); } const String fragment = R"(#version 430 core layout(std430) buffer SharedBlock { uint u; } sharedInstance; layout(std430, binding = 4) buffer FragmentBound { uint f; } fragmentBound; -out vec4 colour; -void main() { colour = vec4(float(sharedInstance.u + fragmentBound.f)); } +out vec4 color; +void main() { color = vec4(float(sharedInstance.u + fragmentBound.f)); } )"; const LinkCapture capture = CaptureFromLink({{GL_VERTEX_SHADER, vertex}, {GL_FRAGMENT_SHADER, fragment}}); diff --git a/MobileGL/MG_Test/ShaderTranspiler/StripIoBlockLocationsTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/StripIoBlockLocationsTest.cpp index 078064af..dc5c1b39 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/StripIoBlockLocationsTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/StripIoBlockLocationsTest.cpp @@ -109,7 +109,7 @@ void main() )"; // A stage with no interface block at all: the pass must leave its located varyings alone - // and report that it changed nothing, so the caller declines the re-serialised module. + // and report that it changed nothing, so the caller declines the re-serialized module. const char* kNoBlockTessEvalSource = R"(#version 420 core layout(isolines, point_mode) in; @@ -267,7 +267,7 @@ TEST_F(StripIoBlockLocationsTest, ReportsNoChangeForAStageWithoutInterfaceBlocks Vector output; ShaderCompiler::StripIoBlockLocationsForEssl(input, true, true, strippedAny, output, true); EXPECT_FALSE(strippedAny) << "a stage with no interface block must report nothing stripped, or " - "the caller adopts a re-serialised module for nothing"; + "the caller adopts a re-serialized module for nothing"; // gl_PerVertex is an Input AND an Output block in this stage and must not be touched; the // located plain varyings must not be either. Either way the emitted ESSL is unchanged. if (!output.empty()) { @@ -283,5 +283,5 @@ TEST_F(StripIoBlockLocationsTest, DeclinesWhenNeitherDirectionIsArmed) { Vector output; EXPECT_FALSE(ShaderCompiler::StripIoBlockLocationsForEssl(input, false, false, strippedAny, output, true)); EXPECT_FALSE(strippedAny); - EXPECT_TRUE(output.empty()) << "an unarmed call must not even re-serialise the module"; + EXPECT_TRUE(output.empty()) << "an unarmed call must not even re-serialize the module"; } diff --git a/MobileGL/MG_Test/ShaderTranspiler/TranslationCacheTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/TranslationCacheTest.cpp index ad6ba70f..73aa0d0b 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/TranslationCacheTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/TranslationCacheTest.cpp @@ -9,7 +9,7 @@ // The two-level shader translation memo (MG_Util/ShaderTranspiler/TranslationCache.h). // // A wrong hit here is a silently miscompiled shader, so the cases below are weighted -// heavily towards the KEY rather than towards the plumbing: for each level there is one +// heavily toward the KEY rather than toward the plumbing: for each level there is one // case per input that can change the output, asserting that moving that input alone moves // the key. That is the test that catches an under-specified key, which is the only way // this feature can produce a wrong answer. @@ -481,7 +481,7 @@ TEST_F(TranslationCacheTest, L1KeyMovesWithEveryInputThatMovesTheSpirv) { // map is an OUTPUT of mapIO (TMglGlslIoResolver writes it and never reads it), so it is a // pure function of the stage sources this key already carries in full. It was dropped from // SpirvTranslationKeyInputs with the glslang-capture migration; kKeyLayoutVersion moved to - // 4 so no blob written under the old shape can be honoured. + // 4 so no blob written under the old shape can be honored. { // ShaderCompileBits (0 on both production parse paths; keyed so a future value // cannot alias a module parsed without it) SpirvTranslationKeyInputs v = base; @@ -1328,7 +1328,7 @@ namespace { } // A source no other case in this file uses, so the process-global L1c cache cannot be - // pre-warmed by a neighbour and turn a "must miss" assertion green by accident. + // pre-warmed by a neighbor and turn a "must miss" assertion green by accident. String UniqueFragment(const String& tag) { return "#version 460\n" "in vec3 vPos;\n" @@ -1403,11 +1403,11 @@ TEST_F(TranslationCacheTest, TheParseVerdictKeyIgnoresBackendOnlyDifferences) { EXPECT_TRUE(BuildShaderParseVerdictKey(onA) == BuildShaderParseVerdictKey(onB)); } -// The headline behaviour: a second shader object handed the same source does not parse. +// The headline behavior: a second shader object handed the same source does not parse. // // Synchronous, deliberately. Under async, ShaderCompileAdoptionMap would hand the second // object the FIRST one whole compile node and no second compile would run at all - a -// different (and older) optimisation, which would make this case pass without L1c existing. +// different (and older) optimization, which would make this case pass without L1c existing. TEST_F(TranslationCacheTest, ASecondCompileOfTheSameSourceSkipsTheParse) { const SyncCompileScope sync; const CacheModeScope cacheOn(true); @@ -1524,7 +1524,7 @@ TEST_F(TranslationCacheTest, TheEscapeHatchDisablesL1c) { EXPECT_EQ(after.hits - before.hits, 0u); EXPECT_EQ(after.misses - before.misses, 0u) << "the cache was consulted with the escape hatch set"; EXPECT_EQ(after.inserts - before.inserts, 0u); - // With the level off, BOTH compiles parse - which is the pre-L1c behaviour exactly. + // With the level off, BOTH compiles parse - which is the pre-L1c behavior exactly. EXPECT_TRUE(ShaderHasParse(first)); EXPECT_TRUE(ShaderHasParse(second)); } diff --git a/MobileGL/MG_Test/ShaderTranspiler/UniquifyIoBlockNamesTest.cpp b/MobileGL/MG_Test/ShaderTranspiler/UniquifyIoBlockNamesTest.cpp index 60993a4f..936eedf6 100644 --- a/MobileGL/MG_Test/ShaderTranspiler/UniquifyIoBlockNamesTest.cpp +++ b/MobileGL/MG_Test/ShaderTranspiler/UniquifyIoBlockNamesTest.cpp @@ -249,7 +249,7 @@ TEST_F(UniquifyIoBlockNamesTest, ReportsNothingWhenThePlanNamesNoBlockThisStageD Vector output; ASSERT_TRUE(ShaderCompiler::UniquifyIoBlockNamesForEssl(input, renames, renames, renamed, output, true)); // Empty is what tells the DirectGLES program build to keep the module it already had - // instead of adopting the optimizer's re-serialised copy. + // instead of adopting the optimizer's re-serialized copy. EXPECT_TRUE(renamed.empty()); const String dis = Disassemble(output); diff --git a/MobileGL/MG_Test/State/NegativeApiErrorsTest.cpp b/MobileGL/MG_Test/State/NegativeApiErrorsTest.cpp index bafa2724..eae45f4b 100644 --- a/MobileGL/MG_Test/State/NegativeApiErrorsTest.cpp +++ b/MobileGL/MG_Test/State/NegativeApiErrorsTest.cpp @@ -559,7 +559,7 @@ void main() { g_color = vec4(1); } GL_INVALID_VALUE}, {"glBlitFramebuffer with a filter that is neither GL_NEAREST nor GL_LINEAR", [] { BlitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, GL_COLOR_BUFFER_BIT, GL_NONE); }, GL_INVALID_ENUM}, - {"glBlitFramebuffer of colour+stencil with GL_LINEAR", + {"glBlitFramebuffer of color+stencil with GL_LINEAR", [] { BlitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_LINEAR); }, diff --git a/MobileGL/MG_Test/State/ObjectLifetimeIdTest.cpp b/MobileGL/MG_Test/State/ObjectLifetimeIdTest.cpp index 2cef04a9..fa76a63a 100644 --- a/MobileGL/MG_Test/State/ObjectLifetimeIdTest.cpp +++ b/MobileGL/MG_Test/State/ObjectLifetimeIdTest.cpp @@ -74,7 +74,7 @@ namespace { // 0 is the "this slot holds nothing" value in every memo that stores an // id, so a live object must never be able to answer to a zeroed slot. EXPECT_NE(lifetimeId, 0u) << typeName << " handed out lifetime id 0 (attempt " << attempt - << "), which is the value a zero-initialised memo slot already carries"; + << "), which is the value a zero-initialized memo slot already carries"; EXPECT_GT(lifetimeId, previousId) << typeName << " lifetime ids must be strictly increasing, so an id is never handed out twice " << "(attempt " << attempt << ")"; diff --git a/MobileGL/MG_Test/State/RenderStateTest.cpp b/MobileGL/MG_Test/State/RenderStateTest.cpp index 2b8bdc17..e8f81c12 100644 --- a/MobileGL/MG_Test/State/RenderStateTest.cpp +++ b/MobileGL/MG_Test/State/RenderStateTest.cpp @@ -588,7 +588,7 @@ TEST_F(RenderStateTest, IndexedRectangleQueriesRejectAnOutOfRangeIndex) { // window", which the frontend cannot spell before a surface exists). DirectGLES resolved the two // by looking at the EXTENT and so inverted every deliberately empty box into the full surface - // KHR-GL43.viewport_array.scissor_zero_dimension is exactly that draw, and it came back holding -// the drawn colour where the untouched fill was required. +// the drawn color where the untouched fill was required. // // These drive RenderState directly instead of the GL entry points on purpose: the flag's whole // content is what it says BEFORE the first scissor call of a context, and this binary shares one diff --git a/MobileGL/MG_Test/State/TransformFeedbackLifetimeIdTest.cpp b/MobileGL/MG_Test/State/TransformFeedbackLifetimeIdTest.cpp index 1b0274fa..82325e5a 100644 --- a/MobileGL/MG_Test/State/TransformFeedbackLifetimeIdTest.cpp +++ b/MobileGL/MG_Test/State/TransformFeedbackLifetimeIdTest.cpp @@ -59,7 +59,7 @@ TEST(TransformFeedbackLifetimeIdTest, AnObjectAtARecycledNameCarriesAFreshLifeti context.BindTransformFeedbackObject(name); const Uint64 firstId = context.GetBoundTransformFeedbackLifetimeId(); EXPECT_NE(firstId, 0u) << "a live transform feedback object answered to id 0, which is the value a " - "zero-initialised backend slot already carries"; + "zero-initialized backend slot already carries"; // The default object is a different object and must not share the id. context.BindTransformFeedbackObject(0); diff --git a/MobileGL/MG_Test/Texture/TextureTest.cpp b/MobileGL/MG_Test/Texture/TextureTest.cpp index 4febfd4e..500a2adc 100644 --- a/MobileGL/MG_Test/Texture/TextureTest.cpp +++ b/MobileGL/MG_Test/Texture/TextureTest.cpp @@ -621,7 +621,7 @@ TEST_F(TextureTest, EverySamplerEntryPointRejectsAnUnknownNameWithInvalidOperati // ===================== GL_TEXTURE_BORDER_COLOR (KHR-GL46.texture_border_clamp) ===================== // GL 4.6 core 8.10 / equation 2.2, and 8.11 / equation 2.3: glTexParameteriv normalizes its integer -// components into the floating-point border colour and glGetTexParameteriv converts back. The pair is +// components into the floating-point border color and glGetTexParameteriv converts back. The pair is // exact for small integers, which is what the CTS's samplerparameteri_border_color checks with // {0,1,2,4}; reading the float back with a truncating cast answered {0,0,0,0}. TEST_F(TextureTest, BorderColorIntegerFormNormalizesAndRoundTripsPerEquations22And23) { @@ -644,7 +644,7 @@ TEST_F(TextureTest, BorderColorIntegerFormNormalizesAndRoundTripsPerEquations22A EXPECT_EQ(readBack[3], 4); // The stored value really is the normalized fraction, not the raw integer - otherwise the round - // trip above would pass for the wrong reason (two missing conversions cancelling). + // trip above would pass for the wrong reason (two missing conversions canceling). GLfloat asFloats[4] = {-1.0f, -1.0f, -1.0f, -1.0f}; MG_Impl::GLImpl::GetTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, asFloats); EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR); @@ -668,7 +668,7 @@ TEST_F(TextureTest, BorderColorIntegerFormNormalizesAndRoundTripsPerEquations22A // The sampler-object twin of the test above. It used to pass for the wrong reason: glSamplerParameteriv // and glSamplerParameterIiv were literally the same call, so the raw integers went in and came back -// out unconverted and the two missing conversions cancelled - which also meant a border of 255 set +// out unconverted and the two missing conversions canceled - which also meant a border of 255 set // through glSamplerParameteriv became float 255.0 instead of the spec's ~1.19e-7. TEST_F(TextureTest, SamplerBorderColorSeparatesTheIntegerFormFromTheNormalizedForm) { GLuint sampler = 0; @@ -707,10 +707,10 @@ TEST_F(TextureTest, SamplerBorderColorSeparatesTheIntegerFormFromTheNormalizedFo DrainPendingGlErrors(); } -// A border colour's FORM is state in its own right: the three representations are kept numerically in +// A border color's FORM is state in its own right: the three representations are kept numerically in // step, so a float (0,0,0,1) followed by an integer (0,0,0,1) moves no number at all - but it is a // real change, and the backends memoise on the version. Swallowing it left DirectGLES forwarding the -// colour through glTexParameterfv forever, which is what made an integer border of 255 come back from +// color through glTexParameterfv forever, which is what made an integer border of 255 come back from // an isampler2D as 1132396544 (the IEEE-754 bits of 255.0f). TEST_F(TextureTest, BorderColorFormChangeBumpsTheVersionEvenWhenTheNumbersDoNotMove) { GLuint sampler = 0; @@ -1089,7 +1089,7 @@ TEST_F(TextureTest, EverySamplerScalarPnameConvertsToTheQueriedType) { } // The unsigned spelling of a NEGATIVE float state: the conversion has to go through GLint, since - // a direct float -> GLuint cast of a negative value is undefined behaviour. + // a direct float -> GLuint cast of a negative value is undefined behavior. GLuint negativeAsUnsigned = 0; MG_Impl::GLImpl::GetSamplerParameterIuiv(sampler, GL_TEXTURE_MIN_LOD, &negativeAsUnsigned); EXPECT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR); @@ -1707,12 +1707,12 @@ TEST_F(TextureTest, StencilIndexIsATextureInternalFormatPairedOnlyWithStencilSto ASSERT_NE(textureObject, nullptr); EXPECT_EQ(textureObject->GetFormat(), TextureInternalFormat::StencilIndex8); - // A colour transfer format against stencil storage is still INVALID_OPERATION, so the clear + // A color transfer format against stencil storage is still INVALID_OPERATION, so the clear // the conformance case makes next fails the way it is supposed to. MG_Impl::GLImpl::ClearTexImage(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); ExpectSingleGlError(GL_INVALID_OPERATION); - // ...and the other direction: GL_STENCIL_INDEX against colour storage stays illegal. + // ...and the other direction: GL_STENCIL_INDEX against color storage stays illegal. MG_Impl::GLImpl::TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, nullptr); ExpectSingleGlError(GL_INVALID_OPERATION); } @@ -2436,7 +2436,7 @@ TEST_F(TextureTest, CompressedInternalFormatsResolveToTheirUncompressedStorage) } } -// Resolving to uncompressed storage is a storage decision, not a licence to answer the level +// Resolving to uncompressed storage is a storage decision, not a license to answer the level // queries as if the application had asked for an uncompressed format. GL 4.6 core 8.5 lets the // implementation choose for the GENERIC formats (GL_COMPRESSED_RED and friends), but a SPECIFIC // one commits the level: GL_TEXTURE_COMPRESSED is true, GL_TEXTURE_INTERNAL_FORMAT is the token @@ -2584,7 +2584,7 @@ namespace { // KHR-GL43.copy_image.non_existent_mipmap. Level 1 of a texture that has only level 0 is // not a level: GL 4.6 core 18.3.2 asks for GL_INVALID_VALUE. Until this check existed the -// level travelled all the way into the backends, and DirectVulkan built a VkImageCopy +// level traveled all the way into the backends, and DirectVulkan built a VkImageCopy // naming mip 1 of a VkImage created with one mip - which Adreno answered with a SIGSEGV // inside vkCmdCopyImage, killing the glcts process in the middle of a negative test. TEST_F(TextureTest, CopyImageSubDataRejectsALevelTheTextureDoesNotHave) { @@ -4580,7 +4580,7 @@ TEST(SharedExponentRGB9E5Test, RedundantPackedEncodingIsRGB9E5Only) { // The other three packed 32-bit layouts round-trip through float32 bit-exactly (each field is // either an integer or a unique float encoding), so a GPU readback still serves them - which - // matters because RGB10_A2 and R11F_G11F_B10F ARE colour-renderable and their shadow can + // matters because RGB10_A2 and R11F_G11F_B10F ARE color-renderable and their shadow can // legitimately be stale. EXPECT_FALSE(HasRedundantPackedEncoding(TextureInternalFormat::RGB10A2)); EXPECT_FALSE(HasRedundantPackedEncoding(TextureInternalFormat::RGB10A2UI)); @@ -4895,9 +4895,9 @@ TEST_F(TextureTest, NamedTextureCallKeepsUnitBindingAccountingCoherent) { DrainPendingGlErrors(); } -// ---- Three-channel colour-renderable widening (Complementary Reimagined / Iris) ---------------- +// ---- Three-channel color-renderable widening (Complementary Reimagined / Iris) ---------------- // -// No real OpenGL ES driver renders to a three-channel image, so a colour attachment the +// No real OpenGL ES driver renders to a three-channel image, so a color attachment the // application asked for as GL_RGB8_SNORM or GL_RGB16F has to be stored in the four-channel // sibling. The bit that says so used to be reachable for multisample storage only, which is why // an ordinary GL_TEXTURE_2D attachment in one of those formats had no fallback at all and the @@ -4911,7 +4911,7 @@ TEST_F(TextureTest, ColorAttachableTargetsRequestTheThreeChannelWidening) { capabilities.SupportsRenderSnorm = true; capabilities.SupportsNorm16Texture = true; - // Every image that can be a colour attachment, not just the multisample pair: an ordinary 2D + // Every image that can be a color attachment, not just the multisample pair: an ordinary 2D // texture is what Iris attaches, and it used to be excluded. for (const TextureTarget target : {TextureTarget::Texture2D, TextureTarget::Texture3D, TextureTarget::TextureCubeMap, @@ -4943,7 +4943,7 @@ TEST_F(TextureTest, ColorAttachableTargetsRequestTheThreeChannelWidening) { PixelFormatNormalizeOptionBit::NoSnorm16RenderTarget); // ...and neither can an 8-bit one. That half of the answer used to be missing entirely, which - // is why an R8_SNORM / RG8_SNORM colour attachment got no substitute at all on a driver + // is why an R8_SNORM / RG8_SNORM color attachment got no substitute at all on a driver // without EXT_render_snorm. EXPECT_TRUE(GetRenderTargetNormalizeOptions(noSnormCapabilities, texture2DIndex) & PixelFormatNormalizeOptionBit::NoSnorm8RenderTarget); @@ -4963,10 +4963,10 @@ TEST_F(TextureTest, ColorAttachableTargetsRequestTheThreeChannelWidening) { PixelFormatNormalizeOptionBit::NoSnorm8RenderTarget); } -// ---- Signed-normalized colour-renderable substitution (KHR-GL4x.texture_swizzle on Mali) ------- +// ---- Signed-normalized color-renderable substitution (KHR-GL4x.texture_swizzle on Mali) ------- // // A driver without GL_EXT_render_snorm treats every signed-normalized format as texture-only, so a -// colour attachment in one of them leaves the ES framebuffer incomplete: the draw lands nowhere and +// color attachment in one of them leaves the ES framebuffer incomplete: the draw lands nowhere and // the readback falls through to the CPU shadow, which for a glTexImage2D(..., nullptr) output // texture is all zeroes. The render-target bits used to reach GL_RGB16_SNORM alone, so five of the // eight SNORM formats - and in particular the single-channel GL_R8_SNORM / GL_R16_SNORM that @@ -5305,7 +5305,7 @@ TEST_F(TextureTest, WidenedRenderTargetUploadExpandsThreeChannelDataWithOpaqueAl } // No widening in effect (or nothing to convert): the caller's pointer comes straight back, so - // the sub-rect upload fast path still recognises an unconverted level. + // the sub-rect upload fast path still recognizes an unconverted level. { const Float source[] = {1.0f, 2.0f, 3.0f, 4.0f}; Vector widened; @@ -5340,7 +5340,7 @@ namespace { g_copyTexImage2DCall = {true, target, level, internalformat, width, height}; } - // A colour read framebuffer of the requested sized format, bound to GL_READ_FRAMEBUFFER, which + // A color read framebuffer of the requested sized format, bound to GL_READ_FRAMEBUFFER, which // is what glCopyTexImage2D takes its source base format from. void BindReadFramebufferWithColorFormat(GLenum sizedInternalFormat) { GLuint framebuffer = 0; @@ -5368,7 +5368,7 @@ TEST_F(TextureTest, CopyTexImage2DAcceptsEveryComponentSubsetOfTheReadBuffer) { ASSERT_EQ(MG_Impl::GLImpl::GetError(), GL_NO_ERROR) << "read framebuffer setup itself failed"; // GL 4.6 sec. 8.6: internalformat may name a SUBSET of the read buffer's components. This is - // exactly the list KHR-GL30.api.coverage walks against an rgba8888 colour buffer, and it is + // exactly the list KHR-GL30.api.coverage walks against an rgba8888 color buffer, and it is // also what an ordinary GL app does with glCopyTexImage2D(GL_RGB) from an RGBA8 framebuffer. for (const GLenum internalFormat : {GL_RED, GL_RG, GL_RGB, GL_RGBA}) { BindFreshMutableTexture2D(); @@ -6301,7 +6301,7 @@ TEST_F(TextureTest, CopyImageSubDataDoesNotApplyMipmapCompletenessToMultisampleT // GL 4.6 core 8.11 makes GL_IMAGE_FORMAT_COMPATIBILITY_TYPE readable through every // GetTexParameter form. Three of MobileGL's four getters answered it and glGetTexParameterfv did -// not, so the float query raised GL_INVALID_ENUM and left the caller's float uninitialised +// not, so the float query raised GL_INVALID_ENUM and left the caller's float uninitialized // (KHR-GL4x.shader_image_load_store.basic-api-texParam reads it with both iv and fv and compares // them). Asserted across all four here, because an enum present in three of four parallel // switches is the drift shape that comes back. @@ -7008,8 +7008,8 @@ TEST(EtcDecoder, DecodesTheConformanceSuitesEtc2RgbImage) { } // The EAC half: a block whose multiplier is 0 still moves every texel by the bare modifier, and a -// base of 128 with modifier index 4 (+2 in table 0) reads 130 in the alpha channel; the colour half -// is an individual-mode block of one flat colour (all-zero indices: +2 on 0x88 = 138). +// base of 128 with modifier index 4 (+2 in table 0) reads 130 in the alpha channel; the color half +// is an individual-mode block of one flat color (all-zero indices: +2 on 0x88 = 138). TEST(EtcDecoder, DecodesAnEacAlphaBlockAndAnIndividualModeColourBlock) { Uint8 block[16] = {}; block[0] = 128; // alpha base @@ -7018,7 +7018,7 @@ TEST(EtcDecoder, DecodesAnEacAlphaBlockAndAnIndividualModeColourBlock) { const Uint64 indices = 0x924924924924ull; for (Int i = 0; i < 6; ++i) block[2 + i] = static_cast(indices >> (40 - 8 * i)); - // Colour: individual mode, both subblocks 0x8 per channel, codewords 0, all indices 0. + // Color: individual mode, both subblocks 0x8 per channel, codewords 0, all indices 0. block[8] = 0x88; block[9] = 0x88; block[10] = 0x88; @@ -7055,7 +7055,7 @@ TEST_F(TextureTest, CompressedTexImage2DDecodesEtc2IntoTheTexels) { } } - // A sub-image replace decodes too: the top-left block becomes a flat individual-mode colour. + // A sub-image replace decodes too: the top-left block becomes a flat individual-mode color. const Uint8 flat[8] = {0x88, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00}; MG_Impl::GLImpl::CompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGB8_ETC2, static_cast(sizeof(flat)), flat); diff --git a/MobileGL/MG_Test/Util/DamageTest.cpp b/MobileGL/MG_Test/Util/DamageTest.cpp index ca6b770a..f28c7dcc 100644 --- a/MobileGL/MG_Test/Util/DamageTest.cpp +++ b/MobileGL/MG_Test/Util/DamageTest.cpp @@ -98,7 +98,7 @@ TEST(Damage, NormalizeMergesDownToTheLimitAndStillCoversEverything) { for (const Rect& r : input) EXPECT_TRUE(Covers(region, r, 1000, 700)) << r.X << "," << r.Y; - // Two neighbours and one far away, limit 2: the neighbours merge, the far one stays apart. + // Two neighbors and one far away, limit 2: the neighbors merge, the far one stays apart. Region three = Of({{0, 0, 10, 10}, {10, 0, 10, 10}, {500, 500, 10, 10}}); three.Normalize(1000, 1000, 2); EXPECT_EQ(three, Of({{0, 0, 20, 10}, {500, 500, 10, 10}})); diff --git a/MobileGL/MG_Test/Util/JobNodeTest.cpp b/MobileGL/MG_Test/Util/JobNodeTest.cpp index 5321a662..b7682531 100644 --- a/MobileGL/MG_Test/Util/JobNodeTest.cpp +++ b/MobileGL/MG_Test/Util/JobNodeTest.cpp @@ -368,7 +368,7 @@ TEST(JobNodeCancel, CancelBeforeAnyDispatchSettlesTheNodeAndSkipsTheBody) { EXPECT_TRUE(job->IsTerminal()); EXPECT_FALSE(job->IsComplete()); - // Posting an already-cancelled node is a no-op, not a second run. + // Posting an already-canceled node is a no-op, not a second run. pool.Post(job); job->Wait(); EXPECT_EQ(job->ran.load(), 0u); @@ -425,7 +425,7 @@ TEST(JobNodeCancel, CancelReleasesContinuationsSoDependentsAreNotStranded) { job->Cancel(); EXPECT_EQ(fired.load(), 1u); - job->Wait(); // must not hang: a cancelled pending node is terminal + job->Wait(); // must not hang: a canceled pending node is terminal EXPECT_TRUE(job->IsCancelled()); } diff --git a/MobileGL/MG_Test/Util/LogLevelTest.cpp b/MobileGL/MG_Test/Util/LogLevelTest.cpp index 1dd33fc7..d4a861e5 100644 --- a/MobileGL/MG_Test/Util/LogLevelTest.cpp +++ b/MobileGL/MG_Test/Util/LogLevelTest.cpp @@ -179,7 +179,7 @@ namespace { GTEST_SKIP() << "asserts are live in this configuration; see AssertIsLiveInDebugBuilds"; } else { // If MOBILEGL_ASSERT were live here this would TRAP and take the process - // down, which is the behavioural half of the contract. + // down, which is the behavioral half of the contract. MOBILEGL_ASSERT(false, "this assert must be compiled out at %s", "INFO"); SUCCEED(); } diff --git a/MobileGL/MG_Test/VertexArray/VertexArrayTest.cpp b/MobileGL/MG_Test/VertexArray/VertexArrayTest.cpp index a1fd2c37..8103e925 100644 --- a/MobileGL/MG_Test/VertexArray/VertexArrayTest.cpp +++ b/MobileGL/MG_Test/VertexArray/VertexArrayTest.cpp @@ -301,7 +301,7 @@ TEST_F(VertexArrayTest, CurrentVertexAttributeStorageCoversFullCapacity) { EXPECT_FLOAT_EQ(stored.floatValue[0], 1.0f); EXPECT_FLOAT_EQ(stored.floatValue[3], 4.0f); - // Neighbouring slots keep the GL default of (0, 0, 0, 1). + // Neighboring slots keep the GL default of (0, 0, 0, 1). const auto& untouched = MG_State::pGLContext->GetCurrentVertexAttribute(highIndex - 1); EXPECT_FLOAT_EQ(untouched.floatValue[0], 0.0f); EXPECT_FLOAT_EQ(untouched.floatValue[3], 1.0f); diff --git a/MobileGL/MG_Test/VertexArray/VertexAttribBindingStateTest.cpp b/MobileGL/MG_Test/VertexArray/VertexAttribBindingStateTest.cpp index 61b45075..36fbda7c 100644 --- a/MobileGL/MG_Test/VertexArray/VertexAttribBindingStateTest.cpp +++ b/MobileGL/MG_Test/VertexArray/VertexAttribBindingStateTest.cpp @@ -165,7 +165,7 @@ namespace { void SetUp() override { MobileGL::Initialize(); // A fresh context per case: the state model under test is cumulative, so a leftover - // VAO binding from a neighbour would silently change what "default state" means. + // VAO binding from a neighbor would silently change what "default state" means. MG_State::pGLContext = MakeUnique(); GenVertexArrays(1, &m_vao); BindVertexArray(m_vao); diff --git a/MobileGL/MG_Test/Wire/ClientRecoveryTest.cpp b/MobileGL/MG_Test/Wire/ClientRecoveryTest.cpp index 58b09758..e9e683aa 100644 --- a/MobileGL/MG_Test/Wire/ClientRecoveryTest.cpp +++ b/MobileGL/MG_Test/Wire/ClientRecoveryTest.cpp @@ -8,7 +8,7 @@ // A CLIENT OUTLIVES ITS LOST SESSION. A GPU device loss ends exactly one session on the server // (MultiSessionTest.ADeviceLossEndsOnlyItsOwnSession); this suite is the client's half. A real -// MobileGL client - the EGL and GL entry points, MobileGL's own initialisation, a unix spawn +// MobileGL client - the EGL and GL entry points, MobileGL's own initialization, a unix spawn // session - against the in-process display server, whose debug knob makes the second device check // in the server process (this client's second read-back) report the device lost. // diff --git a/MobileGL/MG_Test/Wire/ConcurrentContextsTest.cpp b/MobileGL/MG_Test/Wire/ConcurrentContextsTest.cpp index 754bfb5a..fb1e815a 100644 --- a/MobileGL/MG_Test/Wire/ConcurrentContextsTest.cpp +++ b/MobileGL/MG_Test/Wire/ConcurrentContextsTest.cpp @@ -10,8 +10,8 @@ // thread of its own, every window with its own context. Normally they all share with one global // context; after a device loss that share context is lost, so the replacements are created without // sharing - one share group per window, drawing at the same time. Each thread here owns a pbuffer, -// a context and a textured draw of its own colour, and reads it back over and over - through the -// exported EGL and GL entry points, which is where the client serialises its threads. +// a context and a textured draw of its own color, and reads it back over and over - through the +// exported EGL and GL entry points, which is where the client serializes its threads. // // Every shape below has one rule in common: a thread's records apply under ITS context, whatever the // other threads bind, release or destroy meanwhile. The shapes differ in what the other threads do: @@ -115,7 +115,7 @@ namespace { return 0xFF000000u | (0x40u + 0x50u * static_cast(index % 3)) << 8 | (0x20u + 0x30u * static_cast(index / 3)); } - // The clear colour of a churn cycle (ReadbackRace): a different one per thread and cycle. + // The clear color of a churn cycle (ReadbackRace): a different one per thread and cycle. Uint32 ChurnColourOf(int index, int cycle) { return 0xFF000000u | (0x10u * static_cast(index)) << 16 | (static_cast(cycle * 7) & 0xFFu) << 8 | 0x80u; @@ -154,7 +154,7 @@ namespace { Uint32 colour = 0; }; - // The thread's program, vertex array and one-texel texture of its own colour. + // The thread's program, vertex array and one-texel texture of its own color. Drawing BuildDrawing(int index, ThreadReport* out) { static const char* kVertex = "#version 330 core\n" diff --git a/MobileGL/MG_Test/Wire/EventForfeitPeerTest.cpp b/MobileGL/MG_Test/Wire/EventForfeitPeerTest.cpp index 6953e3bf..18341032 100644 --- a/MobileGL/MG_Test/Wire/EventForfeitPeerTest.cpp +++ b/MobileGL/MG_Test/Wire/EventForfeitPeerTest.cpp @@ -495,7 +495,7 @@ namespace { control->SendFrame(MobileGLByteSpan{builder.GetBufferPointer(), builder.GetSize()}) == MOBILEGL_OK; } - // A LogFlush that asks for an acknowledgement (ack=false is the REQUEST; the server's answer + // A LogFlush that asks for an acknowledgment (ack=false is the REQUEST; the server's answer // carries ack=true), exactly the frame ClientSession::SyncPeerLog sends - minus the drain that // SyncPeerLog does first. bool SendLogFlush(Client::ClientSession& client, std::uint64_t seq) { @@ -1055,7 +1055,7 @@ namespace { ASSERT_EQ(ServerLog(logBase).find("recv failed"), std::string::npos) << "the flood finished only after the control connection died - the stall was ended by " "TCP_USER_TIMEOUT, not survived"; - // (2) The peer reads again and synchronises its log. + // (2) The peer reads again and synchronizes its log. const char go = 1; ASSERT_EQ(::write(release[1], &go, 1), 1); struct pollfd wait{synced[0], POLLIN, 0}; diff --git a/MobileGL/MG_Test/Wire/FatalFamilyTest.cpp b/MobileGL/MG_Test/Wire/FatalFamilyTest.cpp index 42f4746a..b0e06239 100644 --- a/MobileGL/MG_Test/Wire/FatalFamilyTest.cpp +++ b/MobileGL/MG_Test/Wire/FatalFamilyTest.cpp @@ -108,7 +108,7 @@ TEST(FatalFamily, TheAnchorFamiliesProjectWhereTheirMeaningSays) { // The liveness families are what a WAITING peer attributes to the other side being gone. EXPECT_EQ(FatalCodeForFamily(MGFatalFamily::BarrierTimeout), FatalCode::ServerCrashed); EXPECT_EQ(FatalCodeForFamily(MGFatalFamily::ApplyThreadNotRunning), FatalCode::ServerCrashed); - // An unmigrated verb is a protocol-level "cannot honour this", not a crash. + // An unmigrated verb is a protocol-level "cannot honor this", not a crash. EXPECT_EQ(FatalCodeForFamily(MGFatalFamily::UnmigratedVerb), FatalCode::ProtocolCorruption); } diff --git a/MobileGL/MG_Test/Wire/LogForwardTest.cpp b/MobileGL/MG_Test/Wire/LogForwardTest.cpp index c7e9dd10..3ca5aaa1 100644 --- a/MobileGL/MG_Test/Wire/LogForwardTest.cpp +++ b/MobileGL/MG_Test/Wire/LogForwardTest.cpp @@ -632,7 +632,7 @@ namespace { // The same stall over the real thing: a SocketTransport pair whose far end does not read until // the caller is done. The socket fills, the sender blocks inside SendFrame (as it would on TCP), // and the caller - 20,000 WARN lines of ~600 bytes, ~12 MB, far past any socket buffer - never - // waits on it. Then the far end reads, and what it gets is levelled LogLines with the gap + // waits on it. Then the far end reads, and what it gets is leveled LogLines with the gap // marked. Close() needs no cut: the reader drains. TEST(LogForwardChannel, OverARealSocketThePeerNotReadingNeverHoldsTheCaller) { std::unique_ptr client, server; diff --git a/MobileGL/MG_Test/Wire/MultiSessionTest.cpp b/MobileGL/MG_Test/Wire/MultiSessionTest.cpp index 2bbfd4de..21da8e5b 100644 --- a/MobileGL/MG_Test/Wire/MultiSessionTest.cpp +++ b/MobileGL/MG_Test/Wire/MultiSessionTest.cpp @@ -18,8 +18,8 @@ // * TwoSessionsInOneProcessAreServedAtOnce - both clients are live AT THE SAME TIME and every // Welcome names the SAME server process (red once by restoring the one-at-a-time supervisor: // the second Hello is Refuse{Busy} and `started` is 0). With headless EGL, each session clears -// its own colour and reads it back - the clear's colour travels in that session's records, so a -// read-back that came from the other session's state would be the other colour. +// its own color and reads it back - the clear's color travels in that session's records, so a +// read-back that came from the other session's state would be the other color. // * SameNamesInTwoSessionsDoNotCollide - the two sessions mint the SAME names: the same client // context token (the session's {token -> ContextRuntime} table) and the same allocatable render // state handle and generation (the session's applier table). Both must be accepted, because a @@ -59,7 +59,7 @@ namespace { // ---- a peer this test drives STEP BY STEP, so a case can interleave two sessions: everything // the peer does is decided by the parent over a pipe, and every step answers with a report. - // The two clear colours, packed the way the read-back hands them back (A<<24|B<<16|G<<8|R, + // The two clear colors, packed the way the read-back hands them back (A<<24|B<<16|G<<8|R, // the little-endian bytes of a GL_RGBA/GL_UNSIGNED_BYTE texel). constexpr Uint32 kGreen = 0xFF00FF00u; constexpr Uint32 kRed = 0xFF0000FFu; @@ -67,7 +67,7 @@ namespace { enum PeerOp : Uint32 { kOpApplyRecord = 1, // one record through the applier (no GL) kOpCreateContext = 2, // ServerCreateEGLContext(arg) - the session's context token table - kOpHealthySession = 3, // the rig's whole healthy session, `arg` = the clear colour + kOpHealthySession = 3, // the rig's whole healthy session, `arg` = the clear color kOpStop = 4, // ClientSession::Stop, then the child leaves // P14 S5: mint context `arg` in share group `aux` (a real frontend share-group token, so // two contexts that pass different ones are a NON-shared pair and two that pass the same @@ -286,8 +286,8 @@ TEST_F(MultiSessionFixture, TwoShmSessionsInOneProcessAreServedAtOnce) { << server.Log(); EXPECT_EQ(Count(server.Log(), "SessionLatch{"), 0u) << "a session latched a fault: " << server.Log(); - // THE RENDER HALF, one session at a time, BOTH STILL LIVE: each session's clear colour travels - // in its own records and its read-back must be that colour. (The two sessions' native state is + // THE RENDER HALF, one session at a time, BOTH STILL LIVE: each session's clear color travels + // in its own records and its read-back must be that color. (The two sessions' native state is // P14b's; see this file's header for why the halves are sequential.) const StepReport aGl = a.Step(kOpHealthySession, kGreen); const StepReport bGl = b.Step(kOpHealthySession, kRed); @@ -298,11 +298,11 @@ TEST_F(MultiSessionFixture, TwoShmSessionsInOneProcessAreServedAtOnce) { EXPECT_EQ(aGl.session.applied, 1) << aGl.session.note; EXPECT_EQ(aGl.session.status, Remote::Wire::ReplySink::kStatusOk) << aGl.session.note; EXPECT_EQ(aGl.session.pixel, kGreen) << "session A read back " << std::hex << aGl.session.pixel - << ", not its own clear colour"; + << ", not its own clear color"; EXPECT_EQ(bGl.session.applied, 1) << bGl.session.note; EXPECT_EQ(bGl.session.status, Remote::Wire::ReplySink::kStatusOk) << bGl.session.note; EXPECT_EQ(bGl.session.pixel, kRed) << "session B read back " << std::hex << bGl.session.pixel - << ", not its own clear colour"; + << ", not its own clear color"; b.Close(); a.Close(); @@ -404,8 +404,8 @@ TEST_F(MultiSessionFixture, ClosingOneSessionLeavesTheOtherServing) { // client emits on a real eglMakeCurrent) and then runs a whole clear-and-read-back through that // context. The two peers alternate, so every round crosses a context switch AND a session. // -// THE COLOUR IS THE WITNESS. Green and red are read back only through the applier the record was -// attributed to, so a session that read the other's working state would read the other's colour; +// THE COLOR IS THE WITNESS. Green and red are read back only through the applier the record was +// attributed to, so a session that read the other's working state would read the other's color; // a context that inherited its sibling's cleared inputs would fail the read-back's own // completeness check. Red once by making MGPipeApplier() ignore the resolver: the two contexts of // one session share one applier and one of the two clears lands on top of the other. @@ -472,7 +472,7 @@ TEST_F(MultiSessionFixture, TwoSessionsInterleaveTwoContextsEachWithoutCrossTalk // one session's apply thread and died (Magma's wire funnels did: a failed submit took // Fatal{UnmigratedVerb, "Magma:wire-verb-flush"} and SIGABRT) took the compositor and every other // client down with it. A backend now hands a loss to MGPipeSessionLatch: that session latches -// Fatal{BackendDeviceLost}, declines what it was doing and closes (exit 75), and its neighbours +// Fatal{BackendDeviceLost}, declines what it was doing and closes (exit 75), and its neighbors // keep applying. The loss is the debug knob's (MGPipeDebugDeviceLossDue) - the same device check // the backends make at their readbacks and frame boundaries - because no GPU here faults on // demand: the 2nd check in the process (session A's read-back, after B's) reports "lost". diff --git a/MobileGL/MG_Test/Wire/P12ServerRig.h b/MobileGL/MG_Test/Wire/P12ServerRig.h index 4d477cdf..8eeb8fb2 100644 --- a/MobileGL/MG_Test/Wire/P12ServerRig.h +++ b/MobileGL/MG_Test/Wire/P12ServerRig.h @@ -175,7 +175,7 @@ namespace { // A forked child's "I got there" to the test that forked it: the child writes one byte, the // test waits for it. Made before the fork; the test drops its copy of the child's end right - // after it, so a child that exits without signalling ends the wait too. + // after it, so a child that exits without signaling ends the wait too. class ReadyPipe { public: ReadyPipe() { @@ -470,7 +470,7 @@ namespace { } // A HEALTHY SESSION: one record applied and, with headless EGL, a clear read back - - // PeerLatchTest's session B, verbatim in what it sends. P14 S2: the clear's colour is + // PeerLatchTest's session B, verbatim in what it sends. P14 S2: the clear's color is // HealthySessionWithColor's parameter so a suite that runs several sessions can tell whose // read-back it is reading; HealthySession keeps the two-argument shape every existing // caller takes its address of. @@ -478,7 +478,7 @@ namespace { // THE PACKING IS THE READ-BACK'S OWN, A<<24|B<<16|G<<8|R - a GL_RGBA/GL_UNSIGNED_BYTE // texel little-endian in a Uint32, which is how PeerReport::pixel comes back and how every // expectation on it is written (green (0,1,0,1) is 0xFF00FF00). Decoding it in the other - // order would clear the complement of the colour the caller asked for. + // order would clear the complement of the color the caller asked for. inline void HealthySessionWithColor(Remote::Client::ClientSession& client, PeerReport& r, Uint32 rgba) { P::MGPMemoryBarrier barrier{}; barrier.Bits = 0x2000u; diff --git a/MobileGL/MG_Test/Wire/PeerLatchTest.cpp b/MobileGL/MG_Test/Wire/PeerLatchTest.cpp index c280d5ae..82d6d25d 100644 --- a/MobileGL/MG_Test/Wire/PeerLatchTest.cpp +++ b/MobileGL/MG_Test/Wire/PeerLatchTest.cpp @@ -348,7 +348,7 @@ namespace { } // ------------------------------------------------------------------------------------ - // The raw-record peer driver (F2's, generalised) + // The raw-record peer driver (F2's, generalized) // ------------------------------------------------------------------------------------ constexpr Uint64 Align8(Uint64 value) { @@ -544,7 +544,7 @@ namespace { samplers.Count = 1; const P::MGPipeHandle unboundSampler = P::kMGPipeNullHandle; const P::MGPContextValues context{}; - // A render state with the GL-initial colour writemask. The server reads the mask from + // A render state with the GL-initial color writemask. The server reads the mask from // the bound CSO and nowhere else, so without one a clear writes nothing (the mask is // the struct's zero, not RenderState's all-true constructor). MobileGL::RenderStateParameters params{}; diff --git a/MobileGL/MG_Test/Wire/PersistentMapFaultTest.cpp b/MobileGL/MG_Test/Wire/PersistentMapFaultTest.cpp index 765c4b92..6919e632 100644 --- a/MobileGL/MG_Test/Wire/PersistentMapFaultTest.cpp +++ b/MobileGL/MG_Test/Wire/PersistentMapFaultTest.cpp @@ -20,7 +20,7 @@ // DEVICE produced (docs/archive/notes/p7/device-window-1, // improved-transparency-minecraft-26.3 under inproc: x0 b4000073ac9a5000 against // "fault addr 0x00000073ac9a5000"). That works on any host only because the -// normalisation is written without an architecture guard - masking bits 56-63 is the +// normalization is written without an architecture guard - masking bits 56-63 is the // identity for every valid userspace address off arm64 - and that was a deliberate // choice: an `#if defined(__aarch64__)` would have put the only gate that can catch // this defect on the one platform CI never runs, which is how it reached the phone. @@ -89,7 +89,7 @@ namespace { // ===================================================================================== // THE CASE THAT WOULD HAVE CAUGHT THE DEVICE CRASH ON A HOST, and it runs on every host: -// both addresses are the device's literal ones and the normalisation they need is written +// both addresses are the device's literal ones and the normalization they need is written // without an architecture guard precisely so this can be a gate rather than a phone-only // hope. The predicate must say the kernel's untagged fault address belongs to the slot a // bionic-tagged shadow pointer published. @@ -103,7 +103,7 @@ TEST(PersistentMapFaultOwnership, AKernelsUntaggedFaultAddressIsOwnedByATaggedSh } // The same row without needing the host to ignore a top byte at all: the predicate is fed a -// composed slot, so it runs everywhere and goes red everywhere the normalisation is dropped. +// composed slot, so it runs everywhere and goes red everywhere the normalization is dropped. // This is the case the gate rests on; the one above is the device's literal reproduction. TEST(PersistentMapFaultOwnership, TheOwnershipRowNormalisesBothSidesBeforeItCompares) { SizeT pageIndex = ~static_cast(0); @@ -131,7 +131,7 @@ TEST(PersistentMapFaultOwnership, UntagAddressClearsTheTopByteAndNothingBelowIt) EXPECT_EQ(PersistentMapTracker::UntagAddressForTest(kDeviceTaggedShadowBase), kDeviceKernelFaultAddress) << "bionic's 0xb4 heap tag must come off, or the table and the kernel disagree"; EXPECT_EQ(PersistentMapTracker::UntagAddressForTest(kDeviceKernelFaultAddress), kDeviceKernelFaultAddress) - << "normalising an already-normal address is the identity, or the handler would move " + << "normalizing an already-normal address is the identity, or the handler would move " "a legitimate fault out of its own slot"; // Bit 55 is ADDRESS, not tag: userspace lives in TTBR0 on arm64 and below TASK_SIZE_MAX // on x86-64, and both keep every bit under 56 meaningful. diff --git a/MobileGL/MG_Test/Wire/PipeWireCodecTest.cpp b/MobileGL/MG_Test/Wire/PipeWireCodecTest.cpp index 2c1c9dfa..b71cd485 100644 --- a/MobileGL/MG_Test/Wire/PipeWireCodecTest.cpp +++ b/MobileGL/MG_Test/Wire/PipeWireCodecTest.cpp @@ -881,7 +881,7 @@ TEST_F(PipeWireCodecTest, SetShaderBuffersCarriesBothTailsWhenTheSpanTailIsPrese } TEST_F(PipeWireCodecTest, ResourceSubDataCarriesABlobAndARegionTailTogether) { - // The only row in the catalogue that is BOTH kHasBlob and kVarTail, and the one rule A + // The only row in the catalog that is BOTH kHasBlob and kVarTail, and the one rule A // changes most: the texture half declared Size 0 in monolith "because the byte count is // the server's to compute", which cannot be a bounds check. Wire2 wire; @@ -1403,7 +1403,7 @@ TEST_F(PipeWireCodecTest, ObjectDeathReachesTheSinkWithItsHandleAndKind) { // // Not a sink row: the decoder's arm runs the REAL applier (MGPipeApplySetContextValues), so // the round trip is read back out of gPipeInputs - under a server stamp, because a -// RECORD-SUPPLIED read outside one is the pre-stamp behaviour this build still tests +// RECORD-SUPPLIED read outside one is the pre-stamp behavior this build still tests // elsewhere, and the fields' own poison would otherwise (correctly) refuse the read. TEST_F(PipeWireCodecTest, SetContextValuesRoundTripsIntoPipeInputs) { @@ -1678,7 +1678,7 @@ TEST_F(PipeWireCodecTest, CreateShaderStateCrossesAsOneArchiveAndSixUndeclaredRu desc.SpirvStatus = 1; // The ruling: Reflection names the WHOLE archive - which already carries every stage's // modules - and Spirv[0..5] stay all-zero. Shipping the modules twice would double the - // biggest record in the catalogue for a reader that does not exist. + // biggest record in the catalog for a reader that does not exist. desc.Reflection = wire.Encoder().StageBytes(archive.data(), archive.size()); for (Uint32 i = 0; i < 6; ++i) { EXPECT_EQ(desc.Spirv[i].Size, 0u); @@ -1878,7 +1878,7 @@ TEST_F(PipeWireCodecTest, MaxRecordBytesSeenStaysFarBelowHalfTheRing) { EXPECT_GT(largest, 0u); EXPECT_EQ(largest, 8u + sizeof(MGPDrawInfo) + 64u * sizeof(MGPDrawRange)); EXPECT_LT(largest, wire.Cmd().MaxRecordBytes()); - // The biggest fixed payload in the whole catalogue is MGPProgramDesc at 192 bytes plus + // The biggest fixed payload in the whole catalog is MGPProgramDesc at 192 bytes plus // MGPFramebufferState at 304, so a record only ever grows through its TAIL - which is why // the counter is on the encoder and not a constant. EXPECT_LT(8u + sizeof(MGPFramebufferState), wire.Cmd().MaxRecordBytes()); @@ -1928,7 +1928,7 @@ TEST_F(PipeWireCodecTest, TheCommandRingWrapCountIsWhatTheHeadActuallyDid) { // One trip round and a little more, draining after every record so the producer never meets // its own tail. This is the same shape the split lane has under the verb barrier: one // record in flight at a time, the ring recycled behind it - so a wrap here is a wrap - // there, and not an artefact of a backed-up queue. + // there, and not an artifact of a backed-up queue. const Uint64 records = (Wire2::kCmdBytes / stride) + 3; for (Uint64 i = 1; i < records; ++i) { ASSERT_NE(wire.Encoder().EncodeRecord(MGPWireOp::BindRenderState, &bind, sizeof(bind)), kInvalidSeq) @@ -1945,7 +1945,7 @@ TEST_F(PipeWireCodecTest, TheCommandRingWrapCountIsWhatTheHeadActuallyDid) { // DIVIDES the capacity and the same trip produces no pad at all - measured in the split // lane, where 1310824 bytes of clears and draws through a 1 MiB SEG_CMD reported // ringwraps=1 ringpads=0. That is why exit gate E3(e) asserts the WRAP and only records - // the pad: a gate on the pad count would be a gate on the sizes in the record catalogue. + // the pad: a gate on the pad count would be a gate on the sizes in the record catalog. EXPECT_EQ(Wire2::kCmdBytes % stride, 16u) << "stride " << stride; EXPECT_EQ(wire.Encoder().CmdWrapPads(), 1u); } @@ -1954,7 +1954,7 @@ TEST_F(PipeWireCodecTest, ABigProgramArchiveDoesNotGrowItsRecordAtAll) { // THE POINT OF R-10's "every blob goes through SEG_STAGE": create_shader_state's RECORD is // 8 + sizeof(MGPProgramDesc) == 200 bytes whether the archive is one kilobyte or one // megabyte, because the record carries {Seg, Offset, Size} and nothing else. So - // create_shader_state is one of the SMALLEST records in the catalogue, not the one most + // create_shader_state is one of the SMALLEST records in the catalog, not the one most // likely to approach MaxRecordBytes(); what approaches that cap is a var-tail, and the // archive's own bound is MOBILEGL_IPC_STAGE_MB with a Fatal of its own. Wire2 wire; @@ -2105,10 +2105,10 @@ TEST_F(PipeWireCodecTest, NoReplyIsWrittenForARowTheCatalogueGivesNoReplySlot) { // this case still asserts. // // WHAT CHANGED IS THE ROW IT ASSERTS IT ABOUT (ID-31 fallout, closed by c1 round 2). It - // used to name ResourceCreate and SetTextureParams as rows "the catalogue gives no reply + // used to name ResourceCreate and SetTextureParams as rows "the catalog gives no reply // slot", which ID-31 made false - it gave ResourceCreate the flag, and all four Bool // acceptance rows carry it now. A case that names a kReplySlot row while asserting a row - // has no slot is not testing the rule, it is testing a stale catalogue, so the row moved + // has no slot is not testing the rule, it is testing a stale catalog, so the row moved // to one that genuinely carries kNone and the rule stayed exactly where it was. Wire2 wire; ASSERT_EQ(MGPipeCallFlagsFor(MGPWireOp::ResourceDestroy) & static_cast(kReplySlot), 0u) @@ -2157,7 +2157,7 @@ TEST_F(PipeWireCodecTest, EveryRowThatDoesWriteAReplyCarriesKReplySlot) { TEST_F(PipeWireCodecTest, TheFourAcceptanceRowsAnswerThroughTheSlotAndNotOnlyThroughTheTally) { // R-17's server half, and the reason c1 could not simply write thirty-seven emitters: the - // client asks the CATALOGUE whether a row owns a slot (ClientSession::EmitAndWait), so the + // client asks the CATALOG whether a row owns a slot (ClientSession::EmitAndWait), so the // moment ID-31 gave these rows kReplySlot, a decoder that answered only into // LastAcceptance() left the client parked in the barrier until Fatal{ReplyMissing}. // @@ -2403,7 +2403,7 @@ TEST_F(PipeWireCodecTest, ARecordLargerThanHalfTheRingIsFatalRingOverrun) { // producing side, rather than becoming a nullptr from Reserve that some caller reads as // "the ring is full, wait" - which on an EMPTY ring would be a wait that never ends. // - // The oversized record is a REAL one from the catalogue with a long var-tail, not a forged + // The oversized record is a REAL one from the catalog with a long var-tail, not a forged // header: MGPDrawInfo declares NumDraws and the encoder cross-checks the tail against the // layout that number implies, so this is the shape a genuine emitter bug would take. const ChildResult r = RunInChild([] { @@ -2810,7 +2810,7 @@ TEST_F(PipeWireCodecTest, AnIndirectDrawThatDeclaresRangesIsFatal) { } TEST_F(PipeWireCodecTest, BufferSubDataResidentMayNotDeclareRegions) { - // Its catalogue row has no kVarTail and its applier takes no regions, so a non-zero + // Its catalog row has no kVarTail and its applier takes no regions, so a non-zero // RegionCount is a fault rather than a tail. The layout used to share ResourceSubData's // arm, which REQUIRED 80 bytes of tail the arm then dropped. const ChildResult r = RunInChild([] { diff --git a/MobileGL/MG_Test/Wire/RemoteClientControls.inc b/MobileGL/MG_Test/Wire/RemoteClientControls.inc index a0ba7286..ca5654fb 100644 --- a/MobileGL/MG_Test/Wire/RemoteClientControls.inc +++ b/MobileGL/MG_Test/Wire/RemoteClientControls.inc @@ -1342,7 +1342,7 @@ TEST(RemoteClientControls, ABufferRespecifyTakesNoReplyWhileATextureOneStillDoes // assertion the device cannot make: set the knob as high as it goes and the row must STILL take the // blocking path on a link that cannot retain. // -// THE WINDOW'S OWN BEHAVIOUR IS PINNED ELSEWHERE, ON THE ARM IT SHIPS ON: StreamLinkTest's +// THE WINDOW'S OWN BEHAVIOR IS PINNED ELSEWHERE, ON THE ARM IT SHIPS ON: StreamLinkTest's // declared-answer cases for the store, and the stream-arm window case for the row. That split is // not tidiness - three rounds of this feature were green here while being inert on the device, // because these gates and the device run on different transports. @@ -1468,7 +1468,7 @@ TEST(RemoteClientControls, ARefusedCreateUnlatchesItsObjectAndItsNextCreateBlock std::memset(pixels, 0x21, sizeof(pixels)); Srv::ServerSessionInstance().SetConsumedSubsystems( kMGPipeSubsystemsMigratedAtP4a & ~kMGPipeSubsystemTextureResources); - // ---- one object we can name, then enough neighbours to fill and drain the window ---- + // ---- one object we can name, then enough neighbors to fill and drain the window ---- // The drain is what READS a deferred answer, so the refusal of the first create is only // discovered once later creates have pushed the ring past its ceiling. const auto defineStorage = [&](GLuint name, Int32 extent) { diff --git a/MobileGL/MG_Test/Wire/RemoteClientTest.cpp b/MobileGL/MG_Test/Wire/RemoteClientTest.cpp index 66788f53..1add9905 100644 --- a/MobileGL/MG_Test/Wire/RemoteClientTest.cpp +++ b/MobileGL/MG_Test/Wire/RemoteClientTest.cpp @@ -357,7 +357,7 @@ TEST(RemoteEmitTable, EachUnmigratedShapeRefusalNamesItsOwnShape) { // P5b d1: a class-B draw slot with no session aborts Fatal{NoClientSession, ""} - the // class-B shape - and NOT Fatal{UnmigratedVerb}: that is what distinguishes a flipped slot from -// the stub it replaced, by behaviour rather than by pointer. Red once by: moving DrawElements +// the stub it replaced, by behavior rather than by pointer. Red once by: moving DrawElements // back into MGR_UNMIGRATED_D1_SLOTS - the log then reads UnmigratedVerb. TEST(RemoteEmitTable, AFlippedDrawSlotDemandsASessionRatherThanNamingItselfUnmigrated) { const ChildResult r = RunInChild( @@ -432,7 +432,7 @@ TEST(RemoteEmitTable, AClassBSlotWithNoSessionAbortsRatherThanFallingThrough) { } TEST(RemoteEmitTable, EachI1SlotReachesRequireSessionUnderItsOwnName) { - // The behavioural half: an i1 slot is class B, so with no ClientSession it reaches + // The behavioral half: an i1 slot is class B, so with no ClientSession it reaches // RequireSession and aborts Fatal{NoClientSession, ""} - NOT Fatal{UnmigratedVerb} // (which would mean the flip never happened) and NOT quietly (which is the split lane // running monolith and going green, R-4). The name in the message is the slot's own, which @@ -1441,7 +1441,7 @@ TEST(PipeRouting, TheTablesAreInstalledWithoutAnybodyHavingRememberedTo) { // The gate on the install MECHANISM rather than on the table contents (PipeCatalogueTest // owns the partition). Nothing in this file calls an installer; the tables are installed // because MG_Pipe/PipeRoute.h's inline variable is in this binary, which is the property - // that a static initialiser inside PipeRoute.cpp did NOT have - the linker dropped that + // that a static initializer inside PipeRoute.cpp did NOT have - the linker dropped that // object from every test binary that named no symbol in it, and five CsoCacheTest cases // took a null function pointer. EXPECT_TRUE(MGPipeTablesAreInstalled()); @@ -1539,7 +1539,7 @@ TEST(PipeRouting, TheInstalledClientArmIsWireAndNotMonolithAndEveryRoutedRowMove // WHAT B3 SAYS IS MISSING. PipeCatalogueTest installs and COUNTS the monolith table, so a // client row that was never overwritten stays non-null and still counts - deleting one // `gMGPipe*.X = &Wire_X` assignment left every gate green (the cross-family verifier - // reproduced it: catalogue 32/32, all lanes green). The only thing that catches it is + // reproduced it: catalog 32/32, all lanes green). The only thing that catches it is // observing that the CLIENT install actually MOVED each routed row off the monolith adapter. // // The monolith adapters are kept beside the installed tables (MGPipeMonolith*()), so the @@ -1622,7 +1622,7 @@ TEST(PipeRouting, TheInstalledClientArmIsWireAndNotMonolithAndEveryRoutedRowMove #if MGTEST_HAVE_FORK TEST(PipeRouting, AClientWireRowWithNoSessionRefusesByNameRatherThanApplying) { // THE RUNTIME HALF of B3, and it distinguishes a Wire_* row from the monolith adapter by - // BEHAVIOUR: with the client tables installed and no session, a routed call reaches + // BEHAVIOR: with the client tables installed and no session, a routed call reaches // RequireSession and aborts Fatal{NoClientSession}. The monolith adapter (the deleted- // assignment state) would instead run MGPipeApply* and NOT abort with that string - so the // control goes red the moment a row falls back to monolith. @@ -1642,7 +1642,7 @@ TEST(PipeRouting, AClientWireRowWithNoSessionRefusesByNameRatherThanApplying) { TEST(PipeRouting, ARoutedCallDuringTeardownRefusesByNameNotRunsTheApplier) { // codex 4: UninstallClientWireTables marks the tables uninstalled; a routed call in that // window must abort by name rather than run the applier on the caller. Reverting Uninstall - // to reinstall the monolith adapters (round 2's behaviour) makes this call run the applier + // to reinstall the monolith adapters (round 2's behavior) makes this call run the applier // and NOT abort with this string - the red-once. const ChildResult child = RunInChild([] { InstallClientWireTables(); @@ -3113,7 +3113,7 @@ TEST(RemoteRunAhead, AnEventBurstBehindAnUnwaitedSequenceFlowControlsInsteadOfAb // (what a headless compositor sizes its output from) and reallocate the default framebuffer's // attachments at it; a format-only event must change no size. Red with the drain's // ApplyServerOwnedSurfaceExtent call deleted (exit 93: the query keeps 1920x1080) and with -// ApplySurfaceChangedToClient's extent arm deleted (exit 94: the colour stays at the placeholder's). +// ApplySurfaceChangedToClient's extent arm deleted (exit 94: the color stays at the placeholder's). TEST(RemoteRunAhead, ARepublishedServerWindowExtentResizesTheServerOwnedSurfaceAndTheDefaultFramebuffer) { const auto child = RunInChild([] { StartRunAheadSession(); diff --git a/MobileGL/MG_Test/Wire/RingTest.cpp b/MobileGL/MG_Test/Wire/RingTest.cpp index 0b62cb20..a6ae90f1 100644 --- a/MobileGL/MG_Test/Wire/RingTest.cpp +++ b/MobileGL/MG_Test/Wire/RingTest.cpp @@ -358,10 +358,10 @@ TEST(RingTest, HardDrainBumpsTheGenerationOnlyWhenQuiesced) { TEST(RingTest, CorruptHeaderIsRefusedRatherThanDispatched) { // SEG_CMD is written by the peer process, so a compile-time size assert on - // the record catalogue proves nothing about what is actually in the + // the record catalog proves nothing about what is actually in the // mapping. Hand-build a ring whose first header is impossible (a size that // is not a multiple of 8) and check the consumer refuses it instead of - // dispatching into undefined behaviour. + // dispatching into undefined behavior. alignas(4096) RingControl control{}; InitRingControl(control); std::vector bytes(256, 0); @@ -744,7 +744,7 @@ TEST(RingTest, TheTwoFlagSpacesAreDisjointByTranslation) { // RingProducer::Reserve MASKS kRecPad OUT of whatever the caller passes // (Ring.cpp: `flags & ~kRecPad`). So the worst of the three collisions - a real record // framed as a wrap filler and skipped by Pop - is ALREADY DEFENDED for anyone who goes - // through Reserve. That defence is worth knowing about and worth pinning, because it is + // through Reserve. That defense is worth knowing about and worth pinning, because it is // also exactly one bit wide: the other two collisions pass straight through. RingFixture ring(1024); const std::uint32_t drawVboCallFlags = MGPipeCallFlagsFor(MGPWireOp::DrawVbo); @@ -780,7 +780,7 @@ TEST(RingTest, TheTwoFlagSpacesAreDisjointByTranslation) { // What saves it is the KIND. RingConsumer::Pop skips a record only when it carries kRecPad // AND kind == kRingPadRecordKind (Ring.cpp: `(header.flags & kRecPad) != 0 && header.kind == // kRingPadRecordKind` - "BOTH, not just the flag"). Kind 0 is the wrap filler's and nothing - // else's, because the call catalogue starts at 1. So the stamped record is DELIVERED, lies + // else's, because the call catalog starts at 1. So the stamped record is DELIVERED, lies // and all, and the decoder can reject it by name - which it can only do because it got it. // THE ASSERT AND THE EXPECTS BELOW ARE THE CONTROL ON THAT KIND CHECK: delete the // `&& header.kind == kRingPadRecordKind` half of Pop's condition and this record vanishes diff --git a/MobileGL/MG_Test/Wire/ServerContextLiveTest.cpp b/MobileGL/MG_Test/Wire/ServerContextLiveTest.cpp index 1a63e7f1..d1869e7b 100644 --- a/MobileGL/MG_Test/Wire/ServerContextLiveTest.cpp +++ b/MobileGL/MG_Test/Wire/ServerContextLiveTest.cpp @@ -55,7 +55,7 @@ TEST(ServerContextLiveTest, OneSessionsReleaseDoesNotKillANeighboursContext) { Bool appLive = true; OnSessionThread(*kwinBlock, [&] { kwinLive = MG_Pipe::MGPipeServerContextIsLive(); }); OnSessionThread(*appBlock, [&] { appLive = MG_Pipe::MGPipeServerContextIsLive(); }); - EXPECT_TRUE(kwinLive) << "a neighbour session's release marked this session's context dead"; + EXPECT_TRUE(kwinLive) << "a neighbor session's release marked this session's context dead"; EXPECT_FALSE(appLive); MG_Pipe::g_pipeInputsThreadResolver = previous; diff --git a/MobileGL/MG_Test/Wire/ServerLoopTest.cpp b/MobileGL/MG_Test/Wire/ServerLoopTest.cpp index a521109f..c8d8f744 100644 --- a/MobileGL/MG_Test/Wire/ServerLoopTest.cpp +++ b/MobileGL/MG_Test/Wire/ServerLoopTest.cpp @@ -753,17 +753,17 @@ TEST(ServerLoopTest, TheAffinityStringResolvesToAMaskAndTheMaskIsLogged) { << "the apply thread did not log its resolved affinity mask; an affinity that silently " "did nothing is indistinguishable from one that worked"; EXPECT_NE(log.find("mgl-srv-apply started"), std::string::npos); - // M-4: `off` must be a RECOGNISED string, not fall through to the numeric-parse "not - // recognised" arm. Deleting the `off` branch in RequestedAffinityMask makes off unrecognised; + // M-4: `off` must be a RECOGNIZED string, not fall through to the numeric-parse "not + // recognized" arm. Deleting the `off` branch in RequestedAffinityMask makes off unrecognized; // this asserts it did not, so that branch's deletion goes red here (its own reason). EXPECT_EQ(log.find("is not `auto`, `off` or a number"), std::string::npos) - << "`off` was treated as an unrecognised affinity string; its own branch is gone"; + << "`off` was treated as an unrecognized affinity string; its own branch is gone"; fixture.Stop(); MG_Config::Ipc.ServerAffinity = saved; } -// M-4, the explicit-mask half: an EXPLICIT mask the box can honour must resolve to itself and be +// M-4, the explicit-mask half: an EXPLICIT mask the box can honor must resolve to itself and be // LOGGED. `off` -> 0 and `0x3` -> 0x3 are two answers that must DIFFER, so the resolver cannot be a // constant. This case does NOT gate codex 11's effective-mask read-back - on an unrestricted box the // request and the effective set are the same and `return requested` stays green here (review v2 @@ -773,7 +773,7 @@ TEST(ServerLoopTest, TheAffinityStringResolvesToAMaskAndTheMaskIsLogged) { TEST(ServerLoopTest, TheExplicitAffinityMaskResolvesToItselfAndIsLogged) { #if defined(__linux__) || defined(__ANDROID__) if (std::thread::hardware_concurrency() < 2) { - GTEST_SKIP() << "needs at least 2 online cpus to honour 0x3"; + GTEST_SKIP() << "needs at least 2 online cpus to honor 0x3"; } const String saved = MG_Config::Ipc.ServerAffinity; MG_Config::Ipc.ServerAffinity = "0x3"; // cpu 0 and cpu 1, both online on any 2+-cpu box @@ -784,7 +784,7 @@ TEST(ServerLoopTest, TheExplicitAffinityMaskResolvesToItselfAndIsLogged) { ASSERT_TRUE(fixture.WaitUntilTrulyParked()); EXPECT_EQ(Server::ServerLoopInstance().ResolvedAffinityMask(), 0x3u) - << "an explicit mask the box can honour did not resolve to itself (0x3); the effective " + << "an explicit mask the box can honor did not resolve to itself (0x3); the effective " "mask read back from the kernel differs from the request, or the resolver is broken"; const std::string log = ReadLog(); EXPECT_NE(log.find("RESOLVED mask 0x3"), std::string::npos) << "the logged RESOLVED mask is not the effective 0x3"; @@ -1510,7 +1510,7 @@ TEST(ServerLoopTest, TheSevenFormatCapabilityReadsAnswerFromTheServersBackendNot << "the renderbuffer sample clamp answered from the global's probed counts (6), not the server's"; // (B) the null-check reads: global NULL, server present. RGB8_SNORM, not RGB8: the fallback - // normalisation's three-channel widening is APPLICABLE to GL_RGB8_SNORM and not to GL_RGB8 + // normalization's three-channel widening is APPLICABLE to GL_RGB8_SNORM and not to GL_RGB8 // (TextureFormatProcessor.cpp's applicability table), so it is the format whose answer the // "no backend" arm actually changes - the first cut of this case used RGB8 and both arms agreed. MG_Backend::pActiveBackendObject.reset(); @@ -1521,7 +1521,7 @@ TEST(ServerLoopTest, TheSevenFormatCapabilityReadsAnswerFromTheServersBackendNot TextureImpl::GenerateTextureFormatInfo(TextureInternalFormat::RGB8Snorm, &internalFormat, &format, &type, TextureTarget::Texture2D); EXPECT_EQ(internalFormat, kGlRgb8Snorm) - << "the format info followed the global (null, so the fallback normalisation widened RGB8_SNORM) " + << "the format info followed the global (null, so the fallback normalization widened RGB8_SNORM) " "instead of the server's backend (present, so native RGB8_SNORM); got 0x" << std::hex << internalFormat; EXPECT_FALSE(TextureImpl::BackendTextureFormatAddsAlpha(TextureInternalFormat::RGB8Snorm, TextureTarget::Texture2D)) @@ -2018,7 +2018,7 @@ namespace { } // THE WINDOW, HELD OPEN. The server acknowledges a record before it looks for the next one, so a - // record published right after that acknowledgement can be popped by the SAME drain, past the + // record published right after that acknowledgment can be popped by the SAME drain, past the // apply loop's per-wake fault poll. The between-records hook makes that happen every time: it // holds the drain after the healthy record until GUILTY is in the ring, and the client publishes // GUILTY once the hold is entered. The hold is armed by the healthy record's seq: the wait for the diff --git a/MobileGL/MG_Test/Wire/ServerOwnedSurfaceTest.cpp b/MobileGL/MG_Test/Wire/ServerOwnedSurfaceTest.cpp index c3565458..df910fe1 100644 --- a/MobileGL/MG_Test/Wire/ServerOwnedSurfaceTest.cpp +++ b/MobileGL/MG_Test/Wire/ServerOwnedSurfaceTest.cpp @@ -7,7 +7,7 @@ // End of Source File Header // P12 (on-screen server window), END TO END ON THE HOST: a real MobileGL client - the EGL entry -// points, MobileGL's own initialisation, the spawn/tcp session - against a real `--serve` supervisor +// points, MobileGL's own initialization, the spawn/tcp session - against a real `--serve` supervisor // that, like every host server, owns NO display. // // What is proven, each on both sides of the wire: diff --git a/MobileGL/MG_Test/Wire/ServerSpawnTest.cpp b/MobileGL/MG_Test/Wire/ServerSpawnTest.cpp index 7ef7351f..bebc0e39 100644 --- a/MobileGL/MG_Test/Wire/ServerSpawnTest.cpp +++ b/MobileGL/MG_Test/Wire/ServerSpawnTest.cpp @@ -981,7 +981,7 @@ TEST(ServerSpawnTest, AnEglControlOpCrossesToTheOtherProcessAndAnswers) { const bool ok = Server::ServerInitializeEGLDisplay(EGL_NO_DISPLAY, &major, &minor); // WHAT IS ASSERTED IS THE ROUND TRIP, not the EGL result. A headless CI - // machine has no display to initialise, so `ok` is expected to be false - + // machine has no display to initialize, so `ok` is expected to be false - // and that is fine, because `cp` is done when the op reaches the other // process and an answer comes back. // @@ -1274,7 +1274,7 @@ TEST(ServerSpawnTest, AnOrderlyStopIsNotADeviceLoss) { TEST(ServerSpawnTest, ADeadBellIsNotAlwaysAHungUpPeer) { // THE ASSERTION THAT MAKES `dl`'s CAUSE/FACT SPLIT LOAD-BEARING, and it exists because the // session-level control above turned out not to. Park() latches m_dead for several reasons - // that are NOT a peer death - POLLERR, POLLNVAL, an unrecognised revents - and each of them + // that are NOT a peer death - POLLERR, POLLNVAL, an unrecognized revents - and each of them // is a fault in THIS process's descriptor. A latch armed from Dead() would report a lost // GPU for a bug in our own fd handling. // diff --git a/MobileGL/MG_Test/Wire/SessionHandshakeTest.cpp b/MobileGL/MG_Test/Wire/SessionHandshakeTest.cpp index 535c5f0c..0bf29931 100644 --- a/MobileGL/MG_Test/Wire/SessionHandshakeTest.cpp +++ b/MobileGL/MG_Test/Wire/SessionHandshakeTest.cpp @@ -346,7 +346,7 @@ TEST(SessionHandshakeTest, ForkRefusesDifferentBuildWithIdenticalWire) { // // Hello.linkTerms carries four byte counts a client may fill in, and nothing on the server reads // them for sizing: Accept builds the segments from its own SetSegmentSizes and Welcome states -// those. That was stated (CONTRACT-P65 LinkTerms) and never pinned, so a refactor that "honoured +// those. That was stated (CONTRACT-P65 LinkTerms) and never pinned, so a refactor that "honored // the client's request" would have handed any peer a 64 GiB allocation per connection. Here a // Hello asks for 64 GiB in every window and the Welcome must come back with the server's own // 4 KiB terms and 4 KiB segments - the allocation that happened is the one Welcome describes. @@ -400,7 +400,7 @@ TEST(SessionHandshakeTest, AHelloAskingFor64GiBIsClampedToTheServersTermsAndAllo EXPECT_EQ(welcome->linkTerms()->maxReplyBytes(), 4096u / sizes.ReplySlotCount - sizeof(Transport::ReplySlotHeader)) << "the reply bound echoed the Hello"; // The segments that EXIST are the server's: each announced size is a few pages at most, never - // the ask. A 64 GiB request that had been honoured would show here even if Welcome's terms + // the ask. A 64 GiB request that had been honored would show here even if Welcome's terms // had been rewritten afterwards. for (const auto* segment : {welcome->cmdRing(), welcome->stageRing(), welcome->replyPool(), welcome->eventRing()}) { ASSERT_NE(segment, nullptr); diff --git a/MobileGL/MG_Test/Wire/SessionTest.cpp b/MobileGL/MG_Test/Wire/SessionTest.cpp index 26a8e3aa..d49fd245 100644 --- a/MobileGL/MG_Test/Wire/SessionTest.cpp +++ b/MobileGL/MG_Test/Wire/SessionTest.cpp @@ -137,7 +137,7 @@ TEST(SessionTest, SessionSegmentsAreRealSharedMemoryAndNotAHeapAllocation) { EXPECT_GE(segments.DescriptorFor(SessionSegmentSlot::Reply), 0); EXPECT_GE(segments.DescriptorFor(SessionSegmentSlot::Event), 0); #endif - // Both control pages start initialised, with the two generations at 1 and every watermark + // Both control pages start initialized, with the two generations at 1 and every watermark // at 0 - the two conventions are opposite on purpose (Ring.h). ASSERT_NE(segments.CmdControl(), nullptr); ASSERT_NE(segments.EventControl(), nullptr); @@ -509,7 +509,7 @@ TEST(SessionTest, RetiredSeqMayTrailTheApplyButCanNeverOvertakeIt) { } // completedFrameSerial: the SERVER's, advanced when a present completes. It trails appliedSeq -// by the GPU's own depth and must never be conflated with it - recycling and ageing wait on +// by the GPU's own depth and must never be conflated with it - recycling and aging wait on // this one and would free a resource the GPU is still reading if they waited on the other. TEST(SessionTest, CompletedFrameSerialIsTheServersAndIsIndependentOfAppliedSeq) { SessionFixture session; diff --git a/MobileGL/MG_Test/Wire/SharedImageTest.cpp b/MobileGL/MG_Test/Wire/SharedImageTest.cpp index 99470ece..3a80053c 100644 --- a/MobileGL/MG_Test/Wire/SharedImageTest.cpp +++ b/MobileGL/MG_Test/Wire/SharedImageTest.cpp @@ -9,7 +9,7 @@ // Shared images: the server's registry, a // session's references, and the aux-socket inbox that carries an import's descriptor beside T0's // Offers. On a host the image memory is a memfd, which is enough for everything here: what is -// under test is that a descriptor which travelled through SCM_RIGHTS still names its image. +// under test is that a descriptor which traveled through SCM_RIGHTS still names its image. #include #include @@ -167,7 +167,7 @@ TEST(SharedImage, TheInboxKeepsSharedImageAndT0DescriptorsApart) { EXPECT_EQ(inbox.TakeSharedImageFd(7, 20, &fd, why), Server::AdoptInbox::Outcome::TimedOut); } -// ---- synchronisation. A pipe stands in for a sync_file: its read end polls readable (signaled) +// ---- synchronization. A pipe stands in for a sync_file: its read end polls readable (signaled) // once something is written to it, which is all the registry asks of a fence. namespace { struct FakeFence { @@ -502,8 +502,8 @@ TEST(SharedImageYuv, ThePlaneCopyFillsEveryDestinationLayout) { EXPECT_EQ(chroma16[r * 16 + c], c16[r][c]); } -// The conversion an import's hints select: BT.709 narrow-range codes of saturated colours decode -// to those colours, and the defaults are BT.601 narrow. +// The conversion an import's hints select: BT.709 narrow-range codes of saturated colors decode +// to those colors, and the defaults are BT.601 narrow. TEST(SharedImageYuv, TheConversionDecodesTheHintedColourSpace) { const auto decode = [](const SI::Yuv::Conversion& c, double y, double cb, double cr, double max) { const double in[3] = {y / max - c.Offset[0], cb / max - c.Offset[1], cr / max - c.Offset[2]}; @@ -523,7 +523,7 @@ TEST(SharedImageYuv, TheConversionDecodesTheHintedColourSpace) { for (int i = 0; i < 4; ++i) { const auto rgb = decode(c709, codes[i][0], codes[i][1], codes[i][2], 255.0); for (int k = 0; k < 3; ++k) - EXPECT_NEAR(rgb[k], want[i][k], 0.02) << "colour " << i << " channel " << k; + EXPECT_NEAR(rgb[k], want[i][k], 0.02) << "color " << i << " channel " << k; } // Full range: Y passes through. SI::Yuv::Hints full; diff --git a/MobileGL/MG_Test/Wire/StagedTextureStoreTest.cpp b/MobileGL/MG_Test/Wire/StagedTextureStoreTest.cpp index 41de83a1..7ab5dbaa 100644 --- a/MobileGL/MG_Test/Wire/StagedTextureStoreTest.cpp +++ b/MobileGL/MG_Test/Wire/StagedTextureStoreTest.cpp @@ -337,7 +337,7 @@ TEST(StagedTextureStoreTest, TwoSessionsHoldTheSameHandleAndOneSessionsDropAllSp EnterBucket(1, 10); ASSERT_TRUE(store.IsLevelDefined(key, kTex2DTarget, 0)) - << "a neighbour session's teardown dropped this session's declared level"; + << "a neighbor session's teardown dropped this session's declared level"; EXPECT_TRUE(store.IsCovered(key, kTex2DTarget, 0)); EXPECT_NE(store.AdoptRun(key, kTex2DTarget, 0, IntVec3{4, 4, 1}, 0, kwinBytes.data(), kwinBytes.size()), nullptr); @@ -366,7 +366,7 @@ TEST(StagedTextureStoreTest, OneSessionsBufferDropAllSparesTheOthersShadows) { store.DropAll(); EXPECT_FALSE(store.HasShadow(&appTwin)); - EXPECT_TRUE(store.HasShadow(&kwinTwin)) << "a neighbour session's teardown dropped this session's bytes"; + EXPECT_TRUE(store.HasShadow(&kwinTwin)) << "a neighbor session's teardown dropped this session's bytes"; EXPECT_TRUE(store.IsCovered(&kwinTwin, 0, bytes.size())); t_testBucketSet = false; @@ -991,7 +991,7 @@ TEST(StagedTextureProductionTest, TextureSubDataThroughTheRealOpsTableCopiesAndS desc.Resource = res; desc.Target = static_cast(MG_Pipe::MGPipeResourceTarget::Tex2D); // RGBA8: the 64 bytes below are 4x4 texels of four bytes, and PH-4 bounds the run by the - // declared level's w*h*d*bpp (a zero-initialised format is R8, one byte a texel). + // declared level's w*h*d*bpp (a zero-initialized format is R8, one byte a texel). desc.InternalFormat = static_cast(TextureInternalFormat::RGBA8); desc.Width = 4; desc.Height = 4; diff --git a/MobileGL/MG_Test/Wire/StreamLinkTest.cpp b/MobileGL/MG_Test/Wire/StreamLinkTest.cpp index 25617e7b..c9673a3f 100644 --- a/MobileGL/MG_Test/Wire/StreamLinkTest.cpp +++ b/MobileGL/MG_Test/Wire/StreamLinkTest.cpp @@ -371,7 +371,7 @@ namespace { // PH-7 (4), ID-P7-3, through the Transport factory pair ServerSession::Accept uses so that // session code never names the concrete link (scripts/ci/link_seam_purity.py). In the - // production order: created without a descriptor, endpoints initialised, then bound once. + // production order: created without a descriptor, endpoints initialized, then bound once. // A second bind, and a bind onto a link the factory did not make as a stream, are refused // and leave the descriptor with the caller; the bound link then carries a record. TEST(StreamLinkFactory, DeferredServerLinkBindsOnceAndThenCarriesARecord) { diff --git a/MobileGL/MG_Test/Wire/TwinOwnershipTest.cpp b/MobileGL/MG_Test/Wire/TwinOwnershipTest.cpp index 5a264e18..e6324baf 100644 --- a/MobileGL/MG_Test/Wire/TwinOwnershipTest.cpp +++ b/MobileGL/MG_Test/Wire/TwinOwnershipTest.cpp @@ -206,7 +206,7 @@ namespace { EXPECT_NE(inA, inB); // This is what DropEveryTwinForEndedServerSession now does, and the reason it is scoped: - // it runs on the apply thread of the session that is ENDING, while a neighbour session + // it runs on the apply thread of the session that is ENDING, while a neighbor session // may still be rendering in this process (P14 S2). EXPECT_EQ(table.DropBucketsOfSession(kSessionA), 1u) << "the ended session's group was not dropped"; BindKey(kSessionA, kGroupOne); diff --git a/MobileGL/MG_Util/Async/JobNode.cpp b/MobileGL/MG_Util/Async/JobNode.cpp index 2ebab1a6..ee081057 100644 --- a/MobileGL/MG_Util/Async/JobNode.cpp +++ b/MobileGL/MG_Util/Async/JobNode.cpp @@ -106,7 +106,7 @@ namespace MobileGL::MG_Util::Async { catch (const std::exception& e) { // Asio propagates an exception escaping a handler out of thread_pool::run(), // which means std::terminate for the whole process. Every job boundary contains - // it and reports the job as Cancelled; the joining GL thread then sees a node + // it and reports the job as Canceled; the joining GL thread then sees a node // that produced no result, which is the same shape as an abandoned node. diagnostics.logLines.push_back({MOBILEGL_LOG_LEVEL_DEBUG, std::format("Job body threw: {}", e.what())}); TryTransition(JobState::Running, JobState::Cancelled); diff --git a/MobileGL/MG_Util/Async/JobNode.h b/MobileGL/MG_Util/Async/JobNode.h index 54d70f1f..827c2be4 100644 --- a/MobileGL/MG_Util/Async/JobNode.h +++ b/MobileGL/MG_Util/Async/JobNode.h @@ -20,7 +20,7 @@ namespace MobileGL::MG_Util::Async { Pending, // constructed, not started; may still be sitting in a queue Running, // a worker is inside RunBody() Complete, // RunBody() returned normally and the node's outputs are readable - Cancelled, // abandoned before it started, cancelled mid-run, or threw + Cancelled, // abandoned before it started, canceled mid-run, or threw }; // A GL error a job body wants to raise. Nothing in the compile/link pipeline produces @@ -64,10 +64,10 @@ namespace MobileGL::MG_Util::Async { // // State machine, and the only legal transitions: // Pending -> Running (a worker picked the node up) - // Pending -> Cancelled (cancelled before any worker started it) + // Pending -> Canceled (canceled before any worker started it) // Running -> Complete (RunBody() returned normally) - // Running -> Cancelled (cancelled mid-run, or RunBody() threw) - // Complete and Cancelled are terminal and the node is immutable afterwards, so every + // Running -> Canceled (canceled mid-run, or RunBody() threw) + // Complete and Canceled are terminal and the node is immutable afterwards, so every // reader that observed IsTerminal() may read the outputs without further synchronization. // // enable_shared_from_this because a dependency edge outlives its registrar: a node that @@ -84,13 +84,13 @@ namespace MobileGL::MG_Util::Async { // Lock-free and non-blocking - safe from any thread, including a pool thread. Bool IsTerminal() const; Bool IsComplete() const; // Complete only; this is what backs GL_COMPLETION_STATUS_KHR - Bool IsCancelled() const; // settled AS cancelled - the outcome, not the request + Bool IsCancelled() const; // settled AS canceled - the outcome, not the request JobState State() const; // The cancellation *request*, which is what a body polls to bail out early: a // running job stays Running until its body returns, so IsCancelled() is still false // at that point. Kept separate from IsCancelled() precisely so the two questions - // ("should I stop?" and "did it end up cancelled?") cannot be confused. + // ("should I stop?" and "did it end up canceled?") cannot be confused. Bool IsCancellationRequested() const; // Blocks until the node is terminal. GL thread only: a job body that waited on @@ -101,7 +101,7 @@ namespace MobileGL::MG_Util::Async { // Cooperative and non-blocking. A node that has not started yet goes terminal // immediately, so anything waiting on it or chained behind it is released rather - // than stranded; a running node is flagged and settles as Cancelled when its body + // than stranded; a running node is flagged and settles as Canceled when its body // returns. Because every node owns its inputs and writes only into itself, an // abandoned node is always safe to simply drop - the caller never waits. void Cancel(); diff --git a/MobileGL/MG_Util/Async/ShaderCompilePool.cpp b/MobileGL/MG_Util/Async/ShaderCompilePool.cpp index 96ee6dac..8c931833 100644 --- a/MobileGL/MG_Util/Async/ShaderCompilePool.cpp +++ b/MobileGL/MG_Util/Async/ShaderCompilePool.cpp @@ -145,7 +145,7 @@ namespace MobileGL::MG_Util::Async { Uint DetectShaderCompileThreadCount() { if (const Uint32 configured = MG_Config::Features.AsyncShaderCompileThreads; configured > 0) { - // An explicit request is honoured as given - it is the escape hatch for measuring + // An explicit request is honored as given - it is the escape hatch for measuring // scaling and for working around a device - so it is not squeezed into [1, 4]. return configured; } @@ -203,7 +203,7 @@ namespace MobileGL::MG_Util::Async { void RunOnWorker(SharedPtr node) { tl_isPoolThread = true; // A node that was already handed to Asio when StopAndDrain ran still arrives - // here; cancelling it first turns the dispatch into a state transition instead of + // here; canceling it first turns the dispatch into a state transition instead of // a full compile, so the drain's join() returns promptly. This Cancel() runs // before `mutex` is ever taken in this frame, so it is not subject to the // re-entrancy hazard DispatchLocked's comment describes. @@ -279,7 +279,7 @@ namespace MobileGL::MG_Util::Async { // Enqueueing can throw: the thread_pool construction and asio::post both allocate, // and under memory pressure a throw here would escape glCompileShader leaving the // node Pending with nothing left to dispatch it - the first observable read would - // then block the GL thread forever. Settle the node instead: a cancelled node is a + // then block the GL thread forever. Settle the node instead: a canceled node is a // state every joiner already handles. // // `node` is still valid in the catch for every throw this try can produce. The @@ -299,7 +299,7 @@ namespace MobileGL::MG_Util::Async { } } catch (...) { - MGLOG_E_ONCE("ShaderCompilePool::Post: enqueue failed; cancelling the job so its joiner " + MGLOG_E_ONCE("ShaderCompilePool::Post: enqueue failed; canceling the job so its joiner " "cannot block forever"); if (node) node->Cancel(); return; diff --git a/MobileGL/MG_Util/Async/ShaderCompilePool.h b/MobileGL/MG_Util/Async/ShaderCompilePool.h index 1933f0c9..643aa55a 100644 --- a/MobileGL/MG_Util/Async/ShaderCompilePool.h +++ b/MobileGL/MG_Util/Async/ShaderCompilePool.h @@ -29,7 +29,7 @@ namespace MobileGL::MG_Util::Async { // MOBILEGL_ASYNC_SHADER_COMPILE forces the answer either way; unset keeps the built-in // default above. Falsy is a complete kill switch: it reverts the threading *and* - // withdraws GL_KHR_parallel_shader_compile, so the application behaviour change goes + // withdraws GL_KHR_parallel_shader_compile, so the application behavior change goes // with it. // // This is the pure CONFIGURATION answer, and it is deliberately not affected by @@ -120,7 +120,7 @@ namespace MobileGL::MG_Util::Async { Uint GetMaxConcurrency() const; // Bounded concurrency doubles as the memory bound, and is how - // glMaxShaderCompilerThreadsKHR(n) is honoured: a 300-program pack load cannot put + // glMaxShaderCompilerThreadsKHR(n) is honored: a 300-program pack load cannot put // 300 glslang arenas in flight at once. Clamped to [1, thread count]. void SetMaxConcurrency(Uint n); diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp index fe0fcfff..44dbddd4 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.cpp @@ -1468,7 +1468,7 @@ namespace MobileGL::MG_Util::BackendLoader { // THE GENERATOR OF THIS WHOLE BUG FAMILY, closed here. A bare glGetIntegerv/glGetFloatv // of a pname the driver does not have does two damaging things at once: it leaves the - // local at whatever the declaration initialised it to - an optimistic number the frontend + // local at whatever the declaration initialized it to - an optimistic number the frontend // then advertises as a capability - and it leaves a GL_INVALID_ENUM in the queue where // the next unrelated probe's caller, or the application's first glGetError, gets blamed // for it. The per-stage storage block, fragment interpolation and buffer texture probes @@ -1482,7 +1482,7 @@ namespace MobileGL::MG_Util::BackendLoader { // GL_SMOOTH_LINE_WIDTH_RANGE / GL_SMOOTH_LINE_WIDTH_GRANULARITY (0x0B22 / 0x0B23) are // desktop-only - ES has never had an antialiased line width query - so on a real GLES // driver these two raise GL_INVALID_ENUM. Kept as probes rather than dropped because the - // ANGLE and desktop-GL hosts MobileGL also runs on do answer them; the initialisers are + // ANGLE and desktop-GL hosts MobileGL also runs on do answer them; the initializers are // the GL 4.6 table 23.55 minimum of [1, 1], which is both the honest answer for a driver // that cannot say and what an untouched out-param already holds. glesFuncs.glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, smoothLineWidthRange); @@ -1525,7 +1525,7 @@ namespace MobileGL::MG_Util::BackendLoader { // ES 3.2 core, or EXT_tessellation_shader on 3.1. Probed rather than version-gated so a // 3.1 driver that HAS the extension still gets to answer; the clamp below is what makes a // rejected query safe, since GL 4.6 table 23.66 and ES 3.2 table 21.45 set the same - // minimums the initialisers carry and neither API permits less. + // minimums the initializers carry and neither API permits less. glesFuncs.glGetIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices); glesFuncs.glGetIntegerv(GL_MAX_TESS_GEN_LEVEL, &maxTessGenLevel); maxPatchVertices = std::max(maxPatchVertices, 32); @@ -1876,7 +1876,7 @@ namespace MobileGL::MG_Util::BackendLoader { // Through glesFuncs, like every other capability query here: a bare glGetIntegerv resolves // to MobileGL's own exported entry point, which answers this pname from the very // capability table being filled in - so the driver's real alignment never arrived and the - // backend reported an unconstrained offset it cannot honour. + // backend reported an unconstrained offset it cannot honor. GLint textureBufferOffsetAlignment = 1; glesFuncs.glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &textureBufferOffsetAlignment); // Core in ES 3.2 and in EXT_texture_buffer; an older context rejects the pname and leaves @@ -2118,7 +2118,7 @@ namespace MobileGL::MG_Util::BackendLoader { MGLOG_I(" Avoid sampler mipmap min filter: %s", caps.AvoidSamplerMipmapMinFilter ? "true" : "false"); MGLOG_I(" Avoid explicit LOD bias: %s", caps.AvoidExplicitLodBias ? "true" : "false"); - // Last line of defence. Capability init is the very first thing that touches the driver, + // Last line of defense. Capability init is the very first thing that touches the driver, // so anything it leaves in the error queue surfaces at the APPLICATION's first // glGetError and gets attributed to whatever call the app happened to make. Every group // above drains its own, but a probe added later must not be able to reintroduce the leak. diff --git a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h index 758a635f..b271a7bd 100644 --- a/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h +++ b/MobileGL/MG_Util/BackendLoaders/OpenGL/Loader.h @@ -1092,11 +1092,11 @@ namespace MobileGL { String GLESShadingLanguageVersionString; Bool SupportsPersistentMapping = false; Bool SupportsNorm16Texture = false; - // GL_EXT_render_snorm is present, so the signed-normalized formats are colour-renderable + // GL_EXT_render_snorm is present, so the signed-normalized formats are color-renderable // (and usable as multisample texture storage) rather than texture-only. Bool SupportsRenderSnorm = false; // GL_EXT_color_buffer_float is present, so GL_RGBA16F / GL_RGBA32F / GL_R11F_G11F_B10F - // (and the R/RG float formats) are colour-renderable. ES 3.x core makes them + // (and the R/RG float formats) are color-renderable. ES 3.x core makes them // texture-only, and every Iris shaderpack renders into at least R11F_G11F_B10F, so // without this no shaderpack can work at all. Bool SupportsColorBufferFloat = false; @@ -1113,7 +1113,7 @@ namespace MobileGL { // anisotropy may be forwarded without raising GL_INVALID_ENUM in GLES. Bool SupportsTextureFilterAnisotropy = false; // GL_TEXTURE_BORDER_COLOR and GL_CLAMP_TO_BORDER: ES 3.2 core, or - // EXT/OES_texture_border_clamp before that. Without it every border-colour parameter + // EXT/OES_texture_border_clamp before that. Without it every border-color parameter // raises INVALID_ENUM on the driver, so the syncs have to be gated on it. Bool SupportsTextureBorderClamp = false; // GL_TEXTURE_CUBE_MAP_ARRAY: ES 3.2 core, or EXT/OES_texture_cube_map_array before it. @@ -1314,7 +1314,7 @@ namespace MobileGL { // by block name and member sequence instead. // // Defaults TRUE and stays true when the probe cannot run, because that is the - // behaviour every driver had before the probe existed - a capability like this + // behavior every driver had before the probe existed - a capability like this // must never be assumed broken on a driver nobody measured. Bool SupportsLocatedInterStageIoBlocks = true; // True when a geometry shader's storage writes made AFTER EmitVertex() are dropped @@ -1386,10 +1386,10 @@ namespace MobileGL { Int MaxComputeWorkGroupInvocations = 128; // GL_MAX_COMPUTE_WORK_GROUP_COUNT / _SIZE per axis, as the driver answers // glGetIntegeri_v. Raw: the frontend floors them at the GL minimums itself. The - // initialisers are those minimums, for a context that rejects the query. + // initializers are those minimums, for a context that rejects the query. Int MaxComputeWorkGroupCount[3] = {65535, 65535, 65535}; Int MaxComputeWorkGroupSize[3] = {1024, 1024, 64}; - // GL_MAX_COMPUTE_SHARED_MEMORY_SIZE; the initialiser is the ES 3.1 minimum. The budget + // GL_MAX_COMPUTE_SHARED_MEMORY_SIZE; the initializer is the ES 3.1 minimum. The budget // the subgroup emulation's workgroup scratch has to fit in. Int MaxComputeSharedMemorySize = 16384; // GL_KHR_shader_subgroup on the ES driver, with what it answers for it. Extension-only diff --git a/MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.cpp b/MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.cpp index 485ee46b..1f4cbeb2 100644 --- a/MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.cpp +++ b/MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.cpp @@ -231,7 +231,7 @@ namespace MobileGL::MG_Util::BackendLoader { supportedFeatures.shaderTessellationAndGeometryPointSize == VK_TRUE; caps.SupportsImageCubeArray = supportedFeatures.imageCubeArray == VK_TRUE; { - // Probe the formats a colour render target actually uses. A driver that refuses the flag + // Probe the formats a color render target actually uses. A driver that refuses the flag // for one of them refuses per-slice attachment for that format only, which // VkTextureManager detects and records at image creation; this field just says whether // the capability is worth offering at all. diff --git a/MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.h b/MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.h index dc7e88a6..846bcd80 100644 --- a/MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.h +++ b/MobileGL/MG_Util/BackendLoaders/Vulkan/Loader.h @@ -107,10 +107,10 @@ namespace MobileGL { // (VUID-VkImageViewCreateInfo-viewType-01004), which is every cube map array texture - // both its sampled view and its full view. Bool SupportsImageCubeArray = false; - // VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT on a 3D colour image, i.e. whether one z slice + // VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT on a 3D color image, i.e. whether one z slice // of a GL_TEXTURE_3D texture can be named by a 2D view and attached to a framebuffer. // Vulkan 1.1 core, but per format+usage - this is an OPTIMISTIC summary probed over the - // common colour attachment formats. The authoritative answer is taken per format at + // common color attachment formats. The authoritative answer is taken per format at // image creation in VkTextureManager, which withdraws the flag and remembers the verdict // when a driver refuses it. Bool Supports2DArrayCompatible3DImages = false; diff --git a/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp index 8df858aa..8e63347a 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp @@ -259,7 +259,7 @@ namespace MobileGL { case GL_STENCIL_INDEX8: return TextureInternalFormat::StencilIndex8; // The unsized stencil base format resolves to the only stencil storage there is, the - // same way the unsized colour and depth base formats below resolve to theirs. Returning + // same way the unsized color and depth base formats below resolve to theirs. Returning // Unknown made glTexImage2D(GL_STENCIL_INDEX) an error, which killed the negative // clear-texture cases in their own setup before they could reach the call they test. case GL_STENCIL_INDEX: @@ -477,7 +477,7 @@ namespace MobileGL { switch (v) { case GL_NEAREST: case GL_LINEAR: - return SamplerMipmapMode::None; // 无 mipmap 时 + return SamplerMipmapMode::None; // when there is no mipmap case GL_NEAREST_MIPMAP_NEAREST: case GL_LINEAR_MIPMAP_NEAREST: return SamplerMipmapMode::Nearest; @@ -509,7 +509,7 @@ namespace MobileGL { SamplerCompareMode ConvertGLEnumToSamplerCompareMode(GLenum v) { switch (v) { case 0: - return SamplerCompareMode::None; // 无 compare + return SamplerCompareMode::None; // no compare case GL_COMPARE_REF_TO_TEXTURE: return SamplerCompareMode::CompareToTexture; default: diff --git a/MobileGL/MG_Util/Converters/MGToVk/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToVk/TextureEnumConverter.cpp index 0f601d53..016644a7 100644 --- a/MobileGL/MG_Util/Converters/MGToVk/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToVk/TextureEnumConverter.cpp @@ -290,7 +290,7 @@ namespace MobileGL { case TexturePixelDataType::UnsignedInt1010102: // GL_UNSIGNED_INT_10_10_10_2 is R in bits 22-31, G 12-21, B 2-11, A 0-1 - an // R10G10B10A2 packing Vulkan has no format for at all. Reported as UNDEFINED - // rather than as the A2*10*10*10 neighbours below, which are a different + // rather than as the A2*10*10*10 neighbors below, which are a different // packing: naming one of those would hand a caller a format whose components // sit in the wrong bits. return VK_FORMAT_UNDEFINED; diff --git a/MobileGL/MG_Util/Debug/Log.h b/MobileGL/MG_Util/Debug/Log.h index 0954f052..15063bd9 100644 --- a/MobileGL/MG_Util/Debug/Log.h +++ b/MobileGL/MG_Util/Debug/Log.h @@ -41,8 +41,8 @@ // W or E that sits on such a path must either be latched with one of the _ONCE forms // below or be demoted to MGLOG_D, which production compiles out entirely. // -// The latch is a function-local atomic - zero-initialised before any dynamic -// initialisation runs, so it is safe from any thread at any time, needs no guard +// The latch is a function-local atomic - zero-initialized before any dynamic +// initialization runs, so it is safe from any thread at any time, needs no guard // variable, and costs one relaxed test-and-set on the already-cold failure path. Note // that the latch is per CALL SITE, not per subject: a site that reports "texture %u is // unsupported" reports only the first such texture. That is the intended trade - the diff --git a/MobileGL/MG_Util/Math/FixedPointConversion.h b/MobileGL/MG_Util/Math/FixedPointConversion.h index 7da5110e..2a4f8bd1 100644 --- a/MobileGL/MG_Util/Math/FixedPointConversion.h +++ b/MobileGL/MG_Util/Math/FixedPointConversion.h @@ -16,7 +16,7 @@ namespace MobileGL::MG_Util { // GL 4.6 core 2.3.5 "Fixed-Point Data Conversions", for the 32-bit signed normalized pair that // GL_TEXTURE_BORDER_COLOR is specified and queried in when the NON-"I" integer entry points are // used (glTexParameteriv / glSamplerParameteriv / glGetTexParameteriv / glGetSamplerParameteriv). - // The "I" entry points (TexParameterIiv / Iuiv) carry a raw integer border colour instead and + // The "I" entry points (TexParameterIiv / Iuiv) carry a raw integer border color instead and // must NOT go through these. // // The two directions have to be an exact pair or a legal round trip is destroyed: the CTS writes @@ -39,7 +39,7 @@ namespace MobileGL::MG_Util { // Equation 2.3: round(f * (2^(b-1) - 1)). f is clamped to [-1, 1] first, as the equation's domain // requires; the multiply is done in double so a near-1 float cannot round past INT32_MAX before - // the cast, which is undefined behaviour rather than a saturating one. + // the cast, which is undefined behavior rather than a saturating one. inline Int32 FloatToSignedNormalizedInt32(Float value) { if (std::isnan(value)) return 0; const Float clamped = std::clamp(value, -1.0f, 1.0f); diff --git a/MobileGL/MG_Util/Metrics/PipeStats.cpp b/MobileGL/MG_Util/Metrics/PipeStats.cpp index 0162d54c..d295e298 100644 --- a/MobileGL/MG_Util/Metrics/PipeStats.cpp +++ b/MobileGL/MG_Util/Metrics/PipeStats.cpp @@ -602,7 +602,7 @@ namespace MobileGL::MG_Util::PipeStats { // number, and "0.00" next to a non-zero acc= is the same lie in a smaller font. line += " acc/draw=" + FormatFixed2(accessorCalls, draws); // "bytes/f[...]" only when there IS a frame to divide by; otherwise the bracket is - // labelled "bytes[...]" and carries the window totals verbatim. + // labeled "bytes[...]" and carries the window totals verbatim. line += perFrame ? " bytes/f[" : " bytes["; for (Uint32 i = 0; i < kByteClassCount; ++i) { if (i != 0) { diff --git a/MobileGL/MG_Util/SelfTest/DriverBugProbes.cpp b/MobileGL/MG_Util/SelfTest/DriverBugProbes.cpp index 2021b945..bc91f7d3 100644 --- a/MobileGL/MG_Util/SelfTest/DriverBugProbes.cpp +++ b/MobileGL/MG_Util/SelfTest/DriverBugProbes.cpp @@ -748,7 +748,7 @@ namespace MobileGL::MG_Util::SelfTest { // One vertex shader per round. The `round` term is multiplied by zero, so it changes // nothing about the result and everything about the source text - which is the point: // the corruption only appears from the SECOND separately compiled sampling program - // onward, and a driver that recognised an identical source could hand back the first + // onward, and a driver that recognized an identical source could hand back the first // program's binary and hide it. String BuildMsaaSampleVertexSource(Int sampleIndex, char component, Int round) { return format("#version 320 es\n" @@ -1008,7 +1008,7 @@ namespace MobileGL::MG_Util::SelfTest { Drain(gl); } - // Reads the colour target back and counts the texels the shader did NOT paint with + // Reads the color target back and counts the texels the shader did NOT paint with // kProbePassColor. A negative result means the readback itself failed. Int CountFailedTexels(const GLESFunctionsTable& gl, const ImageDrawTargets& targets) { Vector pixels(static_cast(targets.size) * targets.size * 4, 0); @@ -1225,7 +1225,7 @@ namespace MobileGL::MG_Util::SelfTest { if (!HasMsaaEntryPoints(gl)) return false; // A sample index other than 0 is the whole subject, so a driver that cannot host a - // multisample colour target at all has nothing to say here. + // multisample color target at all has nothing to say here. Drain(gl); GLint maxColorTextureSamples = 0; gl.glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorTextureSamples); @@ -1260,7 +1260,7 @@ namespace MobileGL::MG_Util::SelfTest { swizzledSource = MakeSwizzledMultisampleSource(gl, samples, GL_RED); defaultSwizzleSource = MakeSwizzledMultisampleSource(gl, samples, GL_ALPHA); if (swizzledSource == 0 || defaultSwizzleSource == 0) { - inconclusive = "the driver would not host a filled R32F multisample colour target"; + inconclusive = "the driver would not host a filled R32F multisample color target"; break; } @@ -1529,7 +1529,7 @@ namespace MobileGL::MG_Util::SelfTest { "%d; the glFinish-separated two-draw control missed %d%s", static_cast(subjectFailed), static_cast(measurement.totalTexels), static_cast(emittedFailed), static_cast(controlFailed), - measurement.detected ? " - THE IN-INVOCATION ORDERING IS NOT HONOURED" : ""); + measurement.detected ? " - THE IN-INVOCATION ORDERING IS NOT HONORED" : ""); } while (false); if (inconclusive != nullptr) { @@ -1663,7 +1663,7 @@ namespace MobileGL::MG_Util::SelfTest { Drain(gl); // THE CONTROL: the same blit onto destination layer 0, which is the case no - // implementation gets wrong. It also proves the SOURCE layer is honoured, since the + // implementation gets wrong. It also proves the SOURCE layer is honored, since the // magic byte it looks for only exists on source layer 1 - so a driver that cannot blit // between array layers at all, or that has no working glFramebufferTextureLayer, fails // here and reaches no verdict rather than being reported as having this bug. @@ -1704,12 +1704,12 @@ namespace MobileGL::MG_Util::SelfTest { return DriverBugFinding{"glBlitFramebuffer ignores the destination array layer", DriverBugVerdict::Fixed, "a glBlitFramebuffer whose DRAW framebuffer attaches a non-zero array layer with " "glFramebufferTextureLayer writes to layer 0 instead, and raises no error doing " - "it. Measured here on the colour aspect; the depth aspect behaves the same way on " - "the device this was characterised on. The layer is honoured everywhere else on " + "it. Measured here on the color aspect; the depth aspect behaves the same way on " + "the device this was characterized on. The layer is honored everywhere else on " "the same driver - the blit's own SOURCE layer is read correctly, which is this " "probe's control - so neither layered attachments nor blitting is withdrawn. " "MobileGL performs such a blit with glCopyImageSubData instead, which takes the " - "destination layer explicitly and honours it here, and applies that substitute to " + "destination layer explicitly and honors it here, and applies that substitute to " "the depth and stencil aspects as well; a blit that scales, flips, changes format, " "resolves samples or is clipped by the scissor cannot be expressed as a copy and " "is still handed to the driver"}; @@ -2011,7 +2011,7 @@ namespace MobileGL::MG_Util::SelfTest { SavedState saved; Save(gl, saved); - // The colour mask is not in SavedState - no other probe touches it - so this one saves + // The color mask is not in SavedState - no other probe touches it - so this one saves // and puts back its own. It has to be forced open: a masked channel would read back as // zero and turn a healthy driver into a "payload lost" verdict. GLboolean savedColorMask[4] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}; @@ -2038,7 +2038,7 @@ namespace MobileGL::MG_Util::SelfTest { measurement.detected = true; // The second control, and the one that scopes the repair: the same located // block between a vertex and a fragment stage. It arrives on the driver this - // was characterised on, which is why DirectGLES only drops the qualifier for + // was characterized on, which is why DirectGLES only drops the qualifier for // programs that have a tessellation or geometry stage. A driver where this one // ALSO fails is losing payloads the repair does not reach, and the report says // so rather than implying the fix is complete. @@ -2467,7 +2467,7 @@ namespace MobileGL::MG_Util::SelfTest { if (!R32FMultisampleSwizzleCorrupted(gl)) return std::nullopt; return DriverBugFinding{"R32F multisample fetch through a swizzled alpha", DriverBugVerdict::Unfixable, "texelFetch() on an R32F GL_TEXTURE_2D_MULTISAMPLE texture whose " - "GL_TEXTURE_SWIZZLE_A is not the default returns uninitialised memory - a " + "GL_TEXTURE_SWIZZLE_A is not the default returns uninitialized memory - a " "different value every run - for any sample index other than 0, from the SECOND " "such program in the context onward. The identical fetch with the default alpha " "swizzle, at sample index 0, or through .x instead of .w is correct, so neither " @@ -2505,7 +2505,7 @@ namespace MobileGL::MG_Util::SelfTest { "pre-store value. The identical shader pair with the two halves renamed keeps " "every store, which is what proves the stage's image writes work and only the " "merge is at fault. MobileGL renames the two halves (mg_imageWo_ / mg_imageRo_) so " - "the driver cannot merge them, and application behaviour is correct"}; + "the driver cannot merge them, and application behavior is correct"}; } Optional ProbeImageCoherencyResidualBug(const GLESFunctionsTable& gl) { @@ -2524,7 +2524,7 @@ namespace MobileGL::MG_Util::SelfTest { "today (`coherent` plus memoryBarrierImage()) misses {} ({:.2f}%) on this " "driver. The same dependency split across two draws with a glMemoryBarrier and " "a glFinish between them is clean, so writes do become visible; it is the " - "ordering inside one invocation that is not honoured. MobileGL keeps the " + "ordering inside one invocation that is not honored. MobileGL keeps the " "coherent pair and the barrier - without them every texel is wrong - and a " "shader that reads back its own image write within one invocation cannot be " "relied on here", @@ -2559,7 +2559,7 @@ namespace MobileGL::MG_Util::SelfTest { if (repairDisabled) { detail += ". THE REPAIR IS DISABLED in this process: MOBILEGL_ESPRYT_UNLOCATED_IO_BLOCKS " "is set to force located blocks ON, so DirectGLES emits the location " - "qualifier the driver cannot honour and the payload is lost. Unset the " + "qualifier the driver cannot honor and the payload is lost. Unset the " "variable to get the repair back"; } else { detail += ". MobileGL emits a tessellation/geometry program's interface blocks with no " @@ -2582,7 +2582,7 @@ namespace MobileGL::MG_Util::SelfTest { // reassurance this file exists to refuse. Auto and ForceOn both widen once this // probe has fired. Should POST ever run before env parsing, the field still holds // its Auto default - which is also what the widening itself consults, so the row - // and the behaviour cannot disagree. + // and the behavior cannot disagree. const Bool widened = MG_Config::Features.EsprytWidenPacked16Storage != MG_Config::QuirkOverride::ForceOff; String detail = "the driver stores SOME 16-bit packed images (RGB565 / RGB5_A1 / RGBA4) with the " "R/G/B/A fields packed from the other end of the word - which allocations get the " diff --git a/MobileGL/MG_Util/SelfTest/DriverBugProbes.h b/MobileGL/MG_Util/SelfTest/DriverBugProbes.h index 2921113a..9d64a705 100644 --- a/MobileGL/MG_Util/SelfTest/DriverBugProbes.h +++ b/MobileGL/MG_Util/SelfTest/DriverBugProbes.h @@ -25,7 +25,7 @@ namespace MobileGL::MG_Util::SelfTest { // The inventory comes from CAMPAIGN FINDINGS, not from anything the driver reports. // // EVERY PROBE MUST CARRY A CONTROL. The geometry entry below is why the rule is written - // down: the same defect was first characterised as "this driver drops all geometry-stage + // down: the same defect was first characterized as "this driver drops all geometry-stage // storage-buffer writes", which would have justified withdrawing // GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS entirely. A control showed geometry-stage writes // land perfectly well when they precede EmitVertex(), so the limit is not a lie and @@ -42,7 +42,7 @@ namespace MobileGL::MG_Util::SelfTest { // report only ever lists bugs actually present on this device. enum class DriverBugVerdict : Uint8 { // A MobileGL quirk repairs or substitutes for the defect and the application sees - // correct behaviour. + // correct behavior. Fixed, // There is no substitute. `detail` says what MobileGL does defensively instead, and // what an application can still rely on. @@ -61,10 +61,10 @@ namespace MobileGL::MG_Util::SelfTest { struct LocatedIoBlockMeasurement { // The driver delivers nothing through an inter-stage interface block that carries an // explicit layout(location=) once a geometry stage is in the pipeline. The only field - // any caller's behaviour depends on. + // any caller's behavior depends on. Bool detected = false; // ...and it does the same WITHOUT a geometry stage, i.e. between a vertex and a - // fragment stage. False on the device this was characterised on, and reported because + // fragment stage. False on the device this was characterized on, and reported because // DirectGLES's repair is scoped to tessellation/geometry programs: a driver that // answered true here would be losing block payloads the repair does not reach. Bool alsoAffectsVertexToFragment = false; @@ -100,13 +100,13 @@ namespace MobileGL::MG_Util::SelfTest { // while the control lands correctly. // // Adreno 830 writes to layer 0 whatever layer the DRAW framebuffer's - // glFramebufferTextureLayer attachment names, for colour and depth alike, and raises no + // glFramebufferTextureLayer attachment names, for color and depth alike, and raises no // error. Everything else about the layer works on the same driver, which is what makes this // a blit defect rather than a layered-attachment one. // // THE CONTROL is the same blit onto destination layer 0. It passes on every implementation // that can blit between array layers at all, and because the value it looks for exists only - // on the SOURCE's layer 1 it also proves the source layer is honoured - so a driver with no + // on the SOURCE's layer 1 it also proves the source layer is honored - so a driver with no // working glFramebufferTextureLayer reaches no verdict instead of being reported as this. // // Returns false when an entry point is missing, when the probe's own framebuffers come back @@ -212,7 +212,7 @@ namespace MobileGL::MG_Util::SelfTest { // with a separately linked program each time. Returns true only when the swizzled read goes // wrong while every control read stays right. // - // Adreno 830 returns uninitialised memory - a different value every run - for + // Adreno 830 returns uninitialized memory - a different value every run - for // texelFetch(sampler2DMS, ..., sampleIndex != 0).w on an R32F multisample texture whose // GL_TEXTURE_SWIZZLE_A is not the default, from the SECOND such program in the context // onward. The first program reads correctly, which is why the probe links two. @@ -224,7 +224,7 @@ namespace MobileGL::MG_Util::SelfTest { // simply cannot render R32F, or cannot sample multisample textures at all, would be // reported as having this very specific corruption. // - // Returns false when the driver cannot host the shape (no multisample R32F colour target, + // Returns false when the driver cannot host the shape (no multisample R32F color target, // fewer than two samples, a missing entry point, an incomplete framebuffer): an // inconclusive probe must never be reported as a bug. Restores every piece of GL state it // touches. diff --git a/MobileGL/MG_Util/SelfTest/DriverPost.cpp b/MobileGL/MG_Util/SelfTest/DriverPost.cpp index 84febd52..d0a4f74b 100644 --- a/MobileGL/MG_Util/SelfTest/DriverPost.cpp +++ b/MobileGL/MG_Util/SelfTest/DriverPost.cpp @@ -84,7 +84,7 @@ namespace MobileGL::MG_Util::SelfTest { // // PASS - the backend supports the capability directly. // WARN - the backend does NOT support it directly, but a MobileGL quirk substitutes - // and the application still sees correct behaviour. The detail names the + // and the application still sees correct behavior. The detail names the // substitute and whatever it costs. // FAIL - unsupported, with no substitute: an application that uses it gets wrong // output, a failed draw, or nothing at all. The detail says what breaks. @@ -374,7 +374,7 @@ namespace MobileGL::MG_Util::SelfTest { "per-draw-buffer glColorMaski available (ES 3.2 core or draw_buffers_indexed)"); } else { builder.FailOptional("Indexed color mask", - "no indexed glColorMaski; every per-draw-buffer colour mask collapses " + "no indexed glColorMaski; every per-draw-buffer color mask collapses " "onto draw buffer 0's, so an MRT pass that masks its attachments " "differently writes the wrong channels to all but one of them, with " "nothing to substitute"); @@ -515,13 +515,13 @@ namespace MobileGL::MG_Util::SelfTest { } if (caps.SupportsTextureBorderClamp) { builder.Pass("Texture border clamp", "supported (GL_TEXTURE_BORDER_COLOR reaches the driver, so " - "GL_CLAMP_TO_BORDER samples the colour the application set)"); + "GL_CLAMP_TO_BORDER samples the color the application set)"); } else { builder.FailOptional("Texture border clamp", "not supported (pre-ES 3.2 without GL_EXT/OES_texture_border_clamp); " "GL_TEXTURE_BORDER_COLOR is not synced to the driver at all, so anything " "sampling outside a GL_CLAMP_TO_BORDER texture reads the driver's default " - "border instead of the requested colour, and no wrap mode substitutes for it"); + "border instead of the requested color, and no wrap mode substitutes for it"); } if (caps.SupportsTextureCubeMapArray) { builder.Pass("Texture cube map array", @@ -588,7 +588,7 @@ namespace MobileGL::MG_Util::SelfTest { "and any shader declaring a samplerBuffer fails to compile and " "leaves its program unlinked - every draw using it is a silent " "no-op. MobileGL still reports GL_MAX_TEXTURE_BUFFER_SIZE = {}: " - "the value is a floor it cannot honour, kept because an OpenGL " + "the value is a floor it cannot honor, kept because an OpenGL " "4.x context may not answer 0 and GL has no way to say that a " "core feature is missing", advertisedLimit)); @@ -647,7 +647,7 @@ namespace MobileGL::MG_Util::SelfTest { } if (caps.SupportsRenderSnorm) { builder.Pass("GL_EXT_render_snorm", - "supported (signed-normalized formats are colour-renderable, so an " + "supported (signed-normalized formats are color-renderable, so an " "SNORM render target keeps its own encoding instead of a float substitute)"); } else { builder.Warn("GL_EXT_render_snorm", @@ -663,7 +663,7 @@ namespace MobileGL::MG_Util::SelfTest { if (caps.SupportsColorBufferFloat) { builder.Pass("GL_EXT_color_buffer_float", "supported (GL_R11F_G11F_B10F / GL_RGBA16F / GL_RGBA32F are " - "colour-renderable, which is what every shaderpack renders into)"); + "color-renderable, which is what every shaderpack renders into)"); } else if (caps.SupportsColorBufferHalfFloat) { builder.Warn("GL_EXT_color_buffer_float", "not supported, but GL_EXT_color_buffer_half_float is; 16-bit float render " @@ -672,7 +672,7 @@ namespace MobileGL::MG_Util::SelfTest { } else { builder.Fail("GL_EXT_color_buffer_float", "not supported, and neither is GL_EXT_color_buffer_half_float; no floating-point " - "format is colour-renderable on this driver, so no shaderpack can create its " + "format is color-renderable on this driver, so no shaderpack can create its " "render targets (Iris reports GL_FRAMEBUFFER_UNSUPPORTED and refuses to load)"); } @@ -849,8 +849,8 @@ namespace MobileGL::MG_Util::SelfTest { // "noperspective interpolation" row - a real correctness render, not just a compile. A viewport- // filling quad is drawn with strong perspective (left clip-w 1, right clip-w 8) and a varying that - // runs 0..1 across it. At the screen centre screen-linear interpolation gives 0.5 while perspective- - // correct gives 1/(w+1) ~= 0.11, so reading the centre texel tells the two apart. The varying is + // runs 0..1 across it. At the screen center screen-linear interpolation gives 0.5 while perspective- + // correct gives 1/(w+1) ~= 0.11, so reading the center texel tells the two apart. The varying is // carried either through the native `noperspective` qualifier (extension present) or through the // exact gl_Position.w / gl_FragCoord.w rewrite MobileGL applies when it is absent. Verdict: // PASS - extension present and the native noperspective result is screen-linear; @@ -928,7 +928,7 @@ namespace MobileGL::MG_Util::SelfTest { } const ScopeGuard delProg([&]() { g.glDeleteProgram(prog); }); - // 9x9 so the centre texel (4,4) sits exactly at NDC (0,0). + // 9x9 so the center texel (4,4) sits exactly at NDC (0,0). constexpr GLsizei kDim = 9; GLuint rbo = 0, fbo = 0, vbo = 0; g.glGenRenderbuffers(1, &rbo); @@ -1000,13 +1000,13 @@ namespace MobileGL::MG_Util::SelfTest { return; } - // At the centre: screen-linear -> 0.5 (~128); perspective-correct -> 1/(8+1) ~= 0.111 (~28). + // At the center: screen-linear -> 0.5 (~128); perspective-correct -> 1/(8+1) ~= 0.111 (~28). const float observed = static_cast(center[0]) / 255.0f; const int observedByte = center[0]; constexpr float kScreenLinear = 0.5f; const bool screenLinear = observed > 0.5f * (kScreenLinear + 1.0f / 9.0f); // midpoint ~= 0.306 if (!screenLinear) { - fail(format("the centre texel read {} (~{:.3f}); expected the screen-linear ~0.5 - " + fail(format("the center texel read {} (~{:.3f}); expected the screen-linear ~0.5 - " "interpolation came out perspective-correct, so noperspective does not work here", observedByte, observed)); return; @@ -1014,10 +1014,10 @@ namespace MobileGL::MG_Util::SelfTest { if (native) { builder.Pass( "noperspective interpolation", - pathNote + format("; native noperspective renders screen-linear (centre {} ~= 0.5)", observedByte)); + pathNote + format("; native noperspective renders screen-linear (center {} ~= 0.5)", observedByte)); } else { builder.Warn("noperspective interpolation", - pathNote + format("; the emulation renders screen-linear correctly (centre {} ~= 0.5), " + pathNote + format("; the emulation renders screen-linear correctly (center {} ~= 0.5), " "but this is the fallback path with less driver coverage", observedByte)); } @@ -1047,7 +1047,7 @@ namespace MobileGL::MG_Util::SelfTest { String nativeList; String widenedList; String unusableList; - // GL_RGB8 is colour-renderable in ES 3.0 CORE. A driver that answers no to it is + // GL_RGB8 is color-renderable in ES 3.0 CORE. A driver that answers no to it is // broken (or the probe itself is), and that is the ONLY three-channel verdict that // deserves a FAIL on its own - see the verdict block below. Bool controlFormatBroken = false; @@ -1092,7 +1092,7 @@ namespace MobileGL::MG_Util::SelfTest { // The verdict deliberately does NOT track "every probed format came out usable". // - // GL_RGB32F widens to GL_RGBA32F, and GL_RGBA32F is colour-renderable only under + // GL_RGB32F widens to GL_RGBA32F, and GL_RGBA32F is color-renderable only under // GL_EXT_color_buffer_float. A perfectly healthy half-float-only driver (the common // mobile shape: EXT_color_buffer_half_float and nothing more) therefore reports // GL_RGB32F as unusable while every format a shaderpack actually renders into works. @@ -1109,28 +1109,28 @@ namespace MobileGL::MG_Util::SelfTest { // row is for. The "no float render targets at all" case is already a FAIL of its own // on the GL_EXT_color_buffer_float row above; repeating it here would only double-count. if (controlFormatBroken) { - builder.Fail("Three-channel colour attachments", - detail + " - GL_RGB8 is colour-renderable in OpenGL ES 3.0 core, so a driver " + builder.Fail("Three-channel color attachments", + detail + " - GL_RGB8 is color-renderable in OpenGL ES 3.0 core, so a driver " "that refuses it cannot render to ANY three-channel attachment and the " "capability probe itself is suspect"); } else if (!unusableList.empty() && caps.SupportsColorBufferFloat) { - builder.Fail("Three-channel colour attachments", + builder.Fail("Three-channel color attachments", detail + " - GL_EXT_color_buffer_float is supported, so the widened " "four-channel float targets are required to be renderable; a framebuffer " "using one of the formats above still reports GL_FRAMEBUFFER_UNSUPPORTED, " "which Iris turns into a hard load failure"); } else if (!unusableList.empty()) { - builder.Warn("Three-channel colour attachments", + builder.Warn("Three-channel color attachments", detail + " - without GL_EXT_color_buffer_float the 32-bit float widening has no " "renderable target left, so a shaderpack asking for one of the formats " "above gets GL_FRAMEBUFFER_UNSUPPORTED; the half-float and fixed-point " "ones above still work"); } else if (!widenedList.empty()) { - builder.Warn("Three-channel colour attachments", + builder.Warn("Three-channel color attachments", detail + " - the substitution costs the extra alpha channel's memory and is " "hidden from the application by an ALPHA->ONE swizzle"); } else { - builder.Pass("Three-channel colour attachments", detail); + builder.Pass("Three-channel color attachments", detail); } } @@ -2766,7 +2766,7 @@ namespace MobileGL::MG_Util::SelfTest { builder.Pass("independentBlend", "per-draw-buffer glColorMaski and indexed blend state supported"); } else { builder.FailOptional("independentBlend", - "unsupported; every attachment takes draw buffer 0's colour mask and " + "unsupported; every attachment takes draw buffer 0's color mask and " "blend state, so an MRT pass that configures them separately writes the " "wrong channels to all but one attachment"); } @@ -2809,13 +2809,13 @@ namespace MobileGL::MG_Util::SelfTest { VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, &sliceProbe) == VK_SUCCESS; if (sliceCapable) { builder.Pass("2D-array-compatible 3D images", - "supported for the common colour attachment formats (one z slice of a " + "supported for the common color attachment formats (one z slice of a " "GL_TEXTURE_3D texture can be attached to a framebuffer and cleared and read " "back on its own; a format that refuses the flag is detected at image " "creation and declines per-slice attachment)"); } else { builder.FailOptional("2D-array-compatible 3D images", - "VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT unavailable for colour " + "VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT unavailable for color " "attachments; glFramebufferTextureLayer on a GL_TEXTURE_3D texture " "is declined for every slice past the first, and a 3D slice cannot " "be rendered into any other way"); diff --git a/MobileGL/MG_Util/SelfTest/DriverPost.h b/MobileGL/MG_Util/SelfTest/DriverPost.h index 1d3731cb..f4cf03ba 100644 --- a/MobileGL/MG_Util/SelfTest/DriverPost.h +++ b/MobileGL/MG_Util/SelfTest/DriverPost.h @@ -18,7 +18,7 @@ namespace MobileGL::MG_Util::SelfTest { // EVERY CAPABILITY ROW IS PASS, WARN OR FAIL; INFO IS FOR IDENTITY ONLY. // PASS - the backend supports the capability directly. // WARN - not directly, but a MobileGL quirk substitutes and the application still sees - // correct behaviour; the detail names the substitute and what it costs. + // correct behavior; the detail names the substitute and what it costs. // FAIL - unsupported with no substitute; an application that uses it gets wrong output, a // failed draw, or nothing. // INFO - identity only: renderer name, API version, driver strings, and the strings diff --git a/MobileGL/MG_Util/SelfTest/PrimitivesGeneratedNoXfbProbe.h b/MobileGL/MG_Util/SelfTest/PrimitivesGeneratedNoXfbProbe.h index db2915c4..415f739d 100644 --- a/MobileGL/MG_Util/SelfTest/PrimitivesGeneratedNoXfbProbe.h +++ b/MobileGL/MG_Util/SelfTest/PrimitivesGeneratedNoXfbProbe.h @@ -73,7 +73,7 @@ namespace MobileGL::MG_Util::SelfTest { // the verdict ranks the dedicated query first. A substitute qualifies only by // answering the exact expected count on every shape it is required to cover; // a device where no substitute qualifies even for the plain shape gets none - // (the honest verdict is the current behaviour); anything that fits neither + // (the honest verdict is the current behavior); anything that fits neither // the defect nor health is INCONCLUSIVE and must never arm anything. The // expected counts are exact (1 triangle per shape), not merely nonzero, so a // driver that half-counts cannot arm a half-right repair. @@ -223,7 +223,7 @@ namespace MobileGL::MG_Util::SelfTest { // The defect is present and no substitute qualifies: none is exact // everywhere, and the plain-only fallback either misses the plain shape // or fails the domination rule above. The honest verdict is the current - // behaviour. + // behavior. Unfixable, }; diff --git a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp index cdd32f01..4ab67eba 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.cpp @@ -467,7 +467,7 @@ namespace MobileGL { // by every stage, and picks it from each shader's own #version: the 460 / // ECoreProfile that ParseShaderSource passes is only the default for a source // without one. So these parses build two tables, 460 core and 330 core, which - // the legacy #version 110-150 shaders normalise to; a shader declaring any + // the legacy #version 110-150 shaders normalize to; a shader declaring any // other version builds its own on first use. static constexpr const char* kPrewarmVertexSource = "#version 460\nvoid main() { gl_Position = vec4(0.0); }\n"; diff --git a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.h b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.h index 554127bf..3aed8fc3 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.h +++ b/MobileGL/MG_Util/ShaderTranspiler/ShaderCompiler.h @@ -692,7 +692,7 @@ namespace MobileGL { // (ParseHelper.cpp vkRelaxedRemapUniformVariable). What this reads is the snapshot // glslang takes at that exact site, handed over through TIntermediate; the GL // location assigner in ProgramLinkTask::DoReflection is the only party left that - // can honour the number. + // can honor the number. // // Keyed by declared name (no "[0]" suffix), plus one synthesized key per outer // index of an array-of-arrays - see the note in the implementation for why diff --git a/MobileGL/MG_Util/ShaderTranspiler/ShaderSourceProcessor.cpp b/MobileGL/MG_Util/ShaderTranspiler/ShaderSourceProcessor.cpp index 979bba50..f305b61c 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/ShaderSourceProcessor.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/ShaderSourceProcessor.cpp @@ -409,7 +409,7 @@ namespace { // '#' follows - which is the ordinary shape of a resolved shader-pack source (one // leading #version, nothing after it), and it makes this whole sweep quadratic in // shader size. A 131 KB glsl-transformer output in .trace-work has exactly one '#' - // in the file. Searching the line span is behaviour-identical: every hashPos the + // in the file. Searching the line span is behavior-identical: every hashPos the // unbounded form could accept already had to satisfy hashPos < lineEnd. if (info.hasValidVersionDirective && probe < lineEnd) { const void* hash = std::memchr(code.data() + probe, '#', lineEnd - probe); @@ -540,7 +540,7 @@ namespace { // gets the second one spliced into the tail of the first - which is exactly what VK-GL-CTS's // ShaderImageLoadStoreBase::BuildProgram does (kGLSLPrec ends without a newline, and // NegativeUniform's own sources begin with "#version 310 es"). Desktop drivers accept it; the - // duplicate says nothing new, so honouring it costs no semantics. + // duplicate says nothing new, so honoring it costs no semantics. // // Blanked rather than erased so that every offset in `info` - which was measured against this // same source - stays valid, and so the line count, and with it __LINE__ and every glslang @@ -957,7 +957,7 @@ namespace { return 0; } - // Whether the shader-language extension `name` is one this backend cannot honour in this + // Whether the shader-language extension `name` is one this backend cannot honor in this // stage - which is what a `#extension name : require` must then fail on, and what an // `enable` must not pretend to have turned on. glslang parses desktop GLSL 4.60, where // these are always available, so without this a shader would compile here and then fail @@ -1072,7 +1072,7 @@ namespace { // block (no other block kind may hold an unsized member at all), only on a member that is not // the last one, and only when every subscript of that member's name in the source is a decimal // literal. Anything outside that shape is left exactly as it was - and the shape itself has no - // correct behaviour today, so the rewrite cannot take a working case away. + // correct behavior today, so the rewrite cannot take a working case away. void SizeNonFinalUnsizedBufferBlockMembers(MobileGL::String& source) { // Both tokens must be present for the shape to exist, and "[]" is absent from essentially // every real shader source, so this is the whole cost for them. @@ -1359,7 +1359,7 @@ namespace { // All-or-nothing, in the discipline of the scanners below it: an array subroutine uniform, a // subroutine token inside a #if arm or a macro body, an unbalanced file, a type that is never // declared - anything outside the grammar abandons the whole pass with the source untouched, - // which is exactly today's behaviour. + // which is exactly today's behavior. void LowerShaderSubroutines(MobileGL::String& source) { if (source.find("subroutine") == MobileGL::String::npos) return; @@ -1773,7 +1773,7 @@ namespace { // extension macro the shader is entitled to disappears with it. A CTS shader guarded by // `#if !GL_OES_sample_variables / this is broken / #endif` then takes the broken branch. // - // The extension BEHAVIOUR survives the rewrite (glslang honours "#extension X : require" under + // The extension BEHAVIOR survives the rewrite (glslang honors "#extension X : require" under // either profile), so this is a preamble-fidelity gap and nothing more; restoring the macros is // the whole fix. // @@ -1793,7 +1793,7 @@ namespace { // preamble defines all of them, and the CTS-shaped "#if !GL_OES_sample_variables" guard // reads one of them. // - // `#extension all : warn` is deliberately NOT honoured here, unlike in the built-in gate. + // `#extension all : warn` is deliberately NOT honored here, unlike in the built-in gate. // The two answer different questions: the gate asks "would glslang have this extension // turned on", where `all` genuinely says yes, while this asks "which preamble macros did // the ES -> desktop rewrite take away". glslang's preamble runs BEFORE any #extension line diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/ClampMultisampleFetchPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/ClampMultisampleFetchPass.cpp index 78ceaeaa..976ed7e3 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/ClampMultisampleFetchPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/ClampMultisampleFetchPass.cpp @@ -115,7 +115,7 @@ namespace MobileGL { // Depth == 1 is the ONLY spelling that positively means a depth image. // glslang writes 0 for a plain sampler and 2 ("no indication") wherever it // cannot tell, and GLSL has no multisampled shadow sampler for it to write 1 - // for, so everything but an explicit 1 falls to the colour ceiling - which is + // for, so everything but an explicit 1 falls to the color ceiling - which is // also the safer of the two to guess at, being the one GL_MAX_SAMPLES itself // describes. Guarded because Depth is only readable on a well-formed type. if (imageType->NumInOperands() > kDepthOperand && @@ -126,7 +126,7 @@ namespace MobileGL { } // An unsigned integer sampled type: the usampler* family, which is what reads the - // stencil aspect of a multisample texture as well as integer colour. + // stencil aspect of a multisample texture as well as integer color. bool HasUnsignedIntegerSampledType(IRContext* context, const Instruction* imageType) { const Instruction* sampledType = context->get_def_use_mgr()->GetDef(imageType->GetSingleWordInOperand(kSampledTypeOperand)); @@ -367,7 +367,7 @@ namespace MobileGL { // Anything that gives up half way - after the import or the bound // constant has been added - would leave a MUTATED module reported as // SuccessWithoutChange, which spvtools::Optimizer asserts against - // (it re-serialises and compares byte for byte in that case). + // (it re-serializes and compares byte for byte in that case). const uint32_t glslStd450Id = EnsureGlslStd450Import(irContext); if (glslStd450Id == 0u) { // Id space exhausted, and the import was NOT added. Nothing has diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/ClampMultisampleFetchPass.h b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/ClampMultisampleFetchPass.h index 8e0f5549..17f82369 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/ClampMultisampleFetchPass.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/ClampMultisampleFetchPass.h @@ -17,7 +17,7 @@ namespace MobileGL { namespace ShaderTranspiler { // GL 4.6 core table 23.53 requires GL_MAX_SAMPLES >= 4, so MobileGL floors every // multisample ceiling it advertises to 4 (GL_Getter's kFrontendMaxSamples) no matter - // what the ES driver reports. The realised allocation cannot be floored the same way - + // what the ES driver reports. The realized allocation cannot be floored the same way - // the driver would simply reject it - so DirectGLES clamps the count it passes to // glTexStorage*Multisample down to what the format really supports // (ClampSamplesToBackendSupport). On Adreno and on Mali's Immortalis-G925 that is ONE @@ -45,17 +45,17 @@ namespace MobileGL { // // Category comes from the OpTypeImage: an OpTypeInt sampled type is the integer // class (GL_MAX_INTEGER_SAMPLES), a float one is depth when the image's Depth operand - // is exactly 1 and colour otherwise. That last clause is deliberate: glslang writes + // is exactly 1 and color otherwise. That last clause is deliberate: glslang writes // Depth 0 for a plain sampler and 2 ("unknown") wherever it cannot tell, and GLSL has // no multisampled shadow sampler at all, so only an explicit 1 is treated as a depth - // image and everything else falls to the colour limit - which is the one a + // image and everything else falls to the color limit - which is the one a // mis-classified image would want anyway. // // An UNSIGNED integer image is the one category whose static ceiling can be wrong - // in both directions: a usampler2DMS reads integer colour formats AND the stencil + // in both directions: a usampler2DMS reads integer color formats AND the stencil // aspect of a multisample STENCIL_INDEX8 / depth-stencil texture, and the backend // allocates the latter under the DEPTH ceiling (Adreno: 4 samples where integer - // colour gets 1). Clamping such a fetch to the integer ceiling reads sample 0 for + // color gets 1). Clamping such a fetch to the integer ceiling reads sample 0 for // every index of a four-sample stencil texture. With deferDirectUnsignedFetches the // caller takes those fetches over at runtime - a per-sampler uniform holding the // bound texture's real last sample index (DirectGLES ClampUnsignedMultisampleFetches) diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/DeriveNumSubgroupsPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/DeriveNumSubgroupsPass.cpp index 6ba46afa..21c28fbd 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/DeriveNumSubgroupsPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/DeriveNumSubgroupsPass.cpp @@ -177,7 +177,7 @@ namespace MobileGL { // REQUIRE_FULL_SUBGROUPS - which ProgramFactory requests whenever // local_size_x is a multiple of the subgroup size makes it legal // (VUID-VkPipelineShaderStageCreateInfo-flags-02759) - and calls the - // tighter behaviour "encouraged" everywhere else; the DriverPost witness + // tighter behavior "encouraged" everywhere else; the DriverPost witness // verifies it per device where the flag cannot be set. The absence of // ALLOW_VARYING_SUBGROUP_SIZE pins only the SubgroupSize builtin itself. // `(count - 1) / size + 1` avoids an addition overflow at count + size - 1. diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FixIterationRPSubgroupScratchPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FixIterationRPSubgroupScratchPass.cpp index 5544e5c9..37b28d4d 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FixIterationRPSubgroupScratchPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FixIterationRPSubgroupScratchPass.cpp @@ -101,7 +101,7 @@ namespace MobileGL { // memory out at natural alignment and the limit // (VUID-RuntimeSpirv-Workgroup-06530) counts the padding that produces, // so a model that sums unpadded sizes would under-count exactly where the - // budget check matters. Returns false for anything not modelled here, + // budget check matters. Returns false for anything not modeled here, // which the caller answers by declining to grow at all rather than by // certifying growth against a total it knows is an underestimate. bool WorkgroupTypeLayout(IRContext* context, uint32_t typeId, uint32_t* size, uint32_t* alignment, diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenAtomicCounterBlockPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenAtomicCounterBlockPass.cpp index 202a5b5d..817b9bcc 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenAtomicCounterBlockPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenAtomicCounterBlockPass.cpp @@ -320,7 +320,7 @@ namespace MobileGL { // it the pass has to work with the one instruction that exists. // // That instruction is not always in a usable place. GetDefiningInstruction only - // honours `position` when it MINTS the constant; when the module already has one + // honors `position` when it MINTS the constant; when the module already has one // it hands back the existing instruction wherever it happens to sit, and glslang // emits constants in first-use order, so a shader whose first use of the value is // below the counter block declares it below the block. The flattened array would diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenFloat64StorageBlockPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenFloat64StorageBlockPass.cpp index bd218889..b451f417 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenFloat64StorageBlockPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenFloat64StorageBlockPass.cpp @@ -500,7 +500,7 @@ namespace MobileGL { return m_context->get_constant_mgr()->GetDefiningInstruction(constant)->result_id(); } - // The word index the chain names, materialised at the chain's own position so + // The word index the chain names, materialized at the chain's own position so // every load and store that uses it is dominated by it. uint32_t WordIndexOf(const ChainPlan& plan) { InstructionBuilder builder(m_context, plan.chain, kPreservedAnalyses); @@ -847,7 +847,7 @@ namespace MobileGL { Binary(builder, spv::Op::OpIEqual, m_boolTypeId, exponent, UintConstant(0xFFu)); // A binary32 subnormal is below every binary64 this can name without a - // normalising loop, so it becomes the signed zero it is nearest to. + // normalizing loop, so it becomes the signed zero it is nearest to. uint32_t high = Select(builder, isMaxExponent, maxHigh, normalHigh); *hi = Select(builder, isZeroExponent, sign, high); *lo = Select(builder, isZeroExponent, UintConstant(0), significandLow); @@ -885,7 +885,7 @@ namespace MobileGL { // spirv-val), so no search for an existing one is needed; the LENGTH CONSTANT is // not exempt, and if the module already declares it after the block there is // nowhere legal to put the array - the block is then declined and keeps today's - // behaviour. Returns 0 for that; an open-ended block has no length constant to + // behavior. Returns 0 for that; an open-ended block has no length constant to // place, so that reason cannot reach it. // // The `uint` element type is a different matter, and only for an OPEN-ENDED diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenXfbInterfaceBlocksPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenXfbInterfaceBlocksPass.cpp index 75c4c4c1..47a82155 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenXfbInterfaceBlocksPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/FlattenXfbInterfaceBlocksPass.cpp @@ -314,7 +314,7 @@ namespace MobileGL { // The entry point's first block, past the leading OpVariable run SPIR-V // requires to stay at the top of a function. Resolved BEFORE anything is // mutated: a decline after the rewrite has started would leave a half-converted - // module behind, and the optimizer serialises whatever the module holds + // module behind, and the optimizer serializes whatever the module holds // regardless of the status this returns. const Uint32 entryFunctionId = entryPoint->GetSingleWordInOperand(1); spvtools::opt::Function* entryFunction = nullptr; diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/Lower1DSampledImagesPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/Lower1DSampledImagesPass.cpp index edfe7e79..7df38295 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/Lower1DSampledImagesPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/Lower1DSampledImagesPass.cpp @@ -106,7 +106,7 @@ namespace MobileGL { Texel, // Reads a property whose result does not depend on Dim. Safe to leave. DimIndependentQuery, - // Recognised, and refused: rewriting the type would change the shape of what + // Recognized, and refused: rewriting the type would change the shape of what // the shader consumes, or the operation is one this pass has no translation // for. Decline, diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/Lower1DSampledImagesPass.h b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/Lower1DSampledImagesPass.h index 6b16a85a..0ac7a939 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/Lower1DSampledImagesPass.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/Lower1DSampledImagesPass.h @@ -96,7 +96,7 @@ namespace MobileGL { // // Every decline is decided BEFORE anything is rewritten - the pass plans the whole // edit, and only then applies it - so there is no state in which it has half-converted - // a module and then given up. Anything it does not recognise reaching one of these + // a module and then given up. Anything it does not recognize reaching one of these // images (a gather, an unexpected image opcode) is a decline, not a guess. class Lower1DSampledImagesPass final : public spvtools::opt::Pass { public: diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerPixelCenterIntegerPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerPixelCenterIntegerPass.cpp index 474b7ad8..35a0852b 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerPixelCenterIntegerPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerPixelCenterIntegerPass.cpp @@ -139,7 +139,7 @@ namespace MobileGL { refused = true; return; } - // z and w keep their values; only the centre of x and y moves. + // z and w keep their values; only the center of x and y moves. if (component >= 2) return; const uint32_t half = scalarOffset(chainUser->type_id(), 0.5f); if (half == 0) { diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerPixelCenterIntegerPass.h b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerPixelCenterIntegerPass.h index 12f6de1c..d59cff6d 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerPixelCenterIntegerPass.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerPixelCenterIntegerPass.h @@ -19,7 +19,7 @@ namespace MobileGL { // environment, which forbids the PixelCenterInteger execution mode // (VUID-StandaloneSpirv-PixelCenterInteger-04654) - a module carrying it fails // validation and DirectVulkan refuses every draw of the program. The mode only moves - // the pixel centre from (n + 0.5) to n, so the pass drops it and subtracts 0.5 from + // the pixel center from (n + 0.5) to n, so the pass drops it and subtracts 0.5 from // x and y of every gl_FragCoord read: whole-vector loads get vec4(0.5, 0.5, 0, 0), // component loads through a constant-index access chain get 0.5 for x and y. // diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerViewportIndexPass.h b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerViewportIndexPass.h index 9e8f9017..6fcd9f3b 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerViewportIndexPass.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/LowerViewportIndexPass.h @@ -26,7 +26,7 @@ namespace MobileGL { // This pass demotes the ViewportIndex OUTPUT to a plain Private global named // mg_ViewportIndex, so the decompiled ESSL declares an ordinary global the shader // still writes and nothing reads. The program compiles and rendering degrades to - // viewport 0 - which is the single-viewport behaviour MG_IntegrationTest's + // viewport 0 - which is the single-viewport behavior MG_IntegrationTest's // ViewportArrayScenario already documents for this backend - instead of the whole // program becoming a no-op. Only meant for the DirectGLES transpile path; the Vulkan // backend keeps the native builtin and routes it for real. diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/NarrowIntegerRuntimeWidths.h b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/NarrowIntegerRuntimeWidths.h index 9eb74a06..c28e9c20 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/NarrowIntegerRuntimeWidths.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/NarrowIntegerRuntimeWidths.h @@ -45,7 +45,7 @@ namespace MobileGL::MG_Util::ShaderTranspiler::NarrowIntegerRuntimeWidths { Bool MaterializeTypes(spvtools::opt::IRContext* context, Ids& ids); ShiftType MaterializeShiftType(spvtools::opt::IRContext* context, const Ids& ids, Uint32 elementTypeId); - // The two named Private globals, initialised to 0 so an unset width reads as "as fetched". + // The two named Private globals, initialized to 0 so an unset width reads as "as fetched". Bool DeclareGlobals(spvtools::opt::IRContext* context, Ids& ids, const std::function& nextId); // Instructions go in before `insertPoint`, which then points past them. diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/RetainGeometryOutputsPass.h b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/RetainGeometryOutputsPass.h index fa4a5d97..7f2021b7 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/RetainGeometryOutputsPass.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/RetainGeometryOutputsPass.h @@ -17,7 +17,7 @@ namespace MobileGL { namespace ShaderTranspiler { // Geometry outputs keep their last written value across EmitVertex(), as on every // desktop GL driver. GLSL leaves them undefined after an emit, but shaders rely on the - // desktop behaviour: iterationT's terrain stage writes `flat out float + // desktop behavior: iterationT's terrain stage writes `flat out float // textureResolution` once and then emits three vertices, and the flat value is taken // from the LAST one (GL's default provoking vertex), which a driver that drops the // value after the first emit renders as random black triangles. diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/StripIoBlockLocationsPass.cpp b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/StripIoBlockLocationsPass.cpp index 09c03c50..4854d1ce 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/StripIoBlockLocationsPass.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/StripIoBlockLocationsPass.cpp @@ -56,7 +56,7 @@ namespace MobileGL { // The interface-block struct an Input/Output variable declares, or 0 when the // variable is not one. Tessellation and geometry interfaces are arrays of the - // block struct, so array levels are unwrapped before the struct is recognised. + // block struct, so array levels are unwrapped before the struct is recognized. uint32_t GetInterfaceBlockStructId(IRContext* irContext, Instruction& variable, const std::unordered_set& blockStructIds, spv::StorageClass& outStorageClass) { diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/StripIoBlockLocationsPass.h b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/StripIoBlockLocationsPass.h index d9be3fe2..f4b6265e 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/StripIoBlockLocationsPass.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/StripIoBlockLocationsPass.h @@ -50,7 +50,7 @@ namespace MobileGL { // them: on the VARIABLE when the cross-stage IO resolver assigned it (or the // application wrote `layout(location=) out Blk {...}`), and on the MEMBERS when the // application located those instead - in which case glslang puts nothing on the - // variable at all and SPIRV-Cross suppresses the block-level qualifier in favour of + // variable at all and SPIRV-Cross suppresses the block-level qualifier in favor of // the member ones. A variable-only strip would silently pass that second shape by. // A struct reached by an interface variable whose direction is NOT armed keeps its // member decorations: they belong to the type, and taking them off would strip the @@ -69,7 +69,7 @@ namespace MobileGL { // `stripInputBlocks` covers the blocks this stage CONSUMES and // `stripOutputBlocks` the ones it PRODUCES. `strippedAny`, when non-null, // receives whether this stage actually had one, so the caller can decline the - // re-serialised module when there was nothing to strip. + // re-serialized module when there was nothing to strip. StripIoBlockLocationsPass(Bool stripInputBlocks, Bool stripOutputBlocks, Bool* strippedAny = nullptr) : m_stripInputBlocks(stripInputBlocks), m_stripOutputBlocks(stripOutputBlocks), m_strippedAny(strippedAny) {} diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/UniquifyIoBlockNamesPass.h b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/UniquifyIoBlockNamesPass.h index 731148c7..47cc8ea5 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/UniquifyIoBlockNamesPass.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpirvPasses/UniquifyIoBlockNamesPass.h @@ -54,7 +54,7 @@ namespace MobileGL { // `inputBlockRenames` applies to blocks this stage CONSUMES and // `outputBlockRenames` to blocks it PRODUCES, both keyed by the block's // current name. `renamedBlockNames` receives the ORIGINAL names this stage - // actually rewrote, so the caller can adopt the re-serialised module only + // actually rewrote, so the caller can adopt the re-serialized module only // when there was something to rewrite. UniquifyIoBlockNamesPass(const std::map& inputBlockRenames, const std::map& outputBlockRenames, diff --git a/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.h b/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.h index cd667627..a61aa5a9 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.h +++ b/MobileGL/MG_Util/ShaderTranspiler/SpvcSession.h @@ -133,7 +133,7 @@ namespace MobileGL { // stages; it may repeat a binding declared by several of them. spvc_result SetAtomicCounterBlockBindings(Int topBinding, Vector& outGlBindings); // Drops the Index decoration from every fragment output that carries the DEFAULT - // colour index 0, so the emitted ESSL does not print `index = 0`. + // color index 0, so the emitted ESSL does not print `index = 0`. // // Index 0 is what every single-source fragment output already is, in GL and in // ESSL alike, and SPIR-V carries the decoration only because the application diff --git a/MobileGL/MG_Util/ShaderTranspiler/TranslationCache.cpp b/MobileGL/MG_Util/ShaderTranspiler/TranslationCache.cpp index f6a26fc7..cac8b362 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/TranslationCache.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/TranslationCache.cpp @@ -20,7 +20,7 @@ namespace MobileGL::MG_Util::ShaderTranspiler { // Bumped whenever the SHAPE of a key changes (a field added, a field's // meaning changed). It is in every blob, so a stale in-memory entry from a - // previous shape cannot be honoured - and a future disk tier gets the same + // previous shape cannot be honored - and a future disk tier gets the same // protection for free. // // 2: L2 gained atomicCounterEsslBindingTop (wave3's atomic-counter block rebinding diff --git a/MobileGL/MG_Util/ShaderTranspiler/TranslationCache.h b/MobileGL/MG_Util/ShaderTranspiler/TranslationCache.h index 7e705ffd..b548496e 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/TranslationCache.h +++ b/MobileGL/MG_Util/ShaderTranspiler/TranslationCache.h @@ -659,7 +659,7 @@ namespace MobileGL::MG_Util::ShaderTranspiler { // names the emitted ESSL spells. Empty for every program without a tessellation or // geometry stage that declares one block name in both directions, i.e. for all but a // handful. The maps rather than what they were derived from: they ARE the pass's - // arguments, so they are exactly as fine as its behaviour and no finer. + // arguments, so they are exactly as fine as its behavior and no finer. const std::map* inputBlockRenames = nullptr; const std::map* outputBlockRenames = nullptr; // THIS STAGE's share of the interface-block LOCATION strip - the two arguments diff --git a/MobileGL/MG_Util/ShaderTranspiler/glslang/TMglGlslIoResolver.cpp b/MobileGL/MG_Util/ShaderTranspiler/glslang/TMglGlslIoResolver.cpp index 2b1ebfe8..ba0bd873 100644 --- a/MobileGL/MG_Util/ShaderTranspiler/glslang/TMglGlslIoResolver.cpp +++ b/MobileGL/MG_Util/ShaderTranspiler/glslang/TMglGlslIoResolver.cpp @@ -266,7 +266,7 @@ namespace MobileGL { // of a storage block's trailing member, and legal on the block instance itself - aborts // the process inside mapIO's collect callback in any build with assertions live. The // repo defines no NDEBUG of its own, so a CMake Debug build is exactly such a build; the - // "reports 0" behaviour the previous comment relied on is only what NDEBUG happens to do. + // "reports 0" behavior the previous comment relied on is only what NDEBUG happens to do. // An unsized array occupies one binding here, which is also what GL means by it. long long elementCount = 1; if (type.isArray() && type.isSizedArray()) { diff --git a/MobileGL/MG_Util/Texture/EtcDecoder.cpp b/MobileGL/MG_Util/Texture/EtcDecoder.cpp index 0e0390cc..b65be892 100644 --- a/MobileGL/MG_Util/Texture/EtcDecoder.cpp +++ b/MobileGL/MG_Util/Texture/EtcDecoder.cpp @@ -85,7 +85,7 @@ namespace MobileGL::MG_Util::EtcDecoder { Int base[2][3] = {}; if (!diff) { - // Individual mode: two 4-bit colours. + // Individual mode: two 4-bit colors. base[0][0] = Extend4(Bits(word, 63, 60)); base[1][0] = Extend4(Bits(word, 59, 56)); base[0][1] = Extend4(Bits(word, 55, 52)); diff --git a/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp b/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp index 8df66869..a4e5bd3a 100644 --- a/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp +++ b/MobileGL/MG_Util/Texture/PixelStoreProcessor.cpp @@ -138,7 +138,7 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { case TextureInternalFormat::DepthComponent32F: out = {1, ShadowComponent::Float32, false}; return true; - // Stencil is the one single-channel INTEGER shadow that is not a colour format: eight + // Stencil is the one single-channel INTEGER shadow that is not a color format: eight // bits, held as an unsigned index rather than a normalized value. case TextureInternalFormat::StencilIndex8: out = {1, ShadowComponent::UInt8, true}; @@ -1192,8 +1192,8 @@ namespace MobileGL::MG_Util::PixelStoreProcessor { outputPixel.clear(); // A stencil index became a transferable format when STENCIL_INDEX8 texture storage did (see // GetUnpackChannelMapping), but this helper serves glClearBufferData, whose internal formats - // are all colour (GL 4.6 core table 8.20): a stencil pattern would otherwise pass the size - // check and land silently in an equally-sized colour store. + // are all color (GL 4.6 core table 8.20): a stencil pattern would otherwise pass the size + // check and land silently in an equally-sized color store. if (textureInputFormat == TextureInputFormat::StencilIndex) return false; if (inputPixel == nullptr || !IsValidUnpackPixelPair(textureInputFormat, inputDataType)) return false; diff --git a/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp b/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp index 97ab4501..803509db 100644 --- a/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp +++ b/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp @@ -32,7 +32,7 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { break; // The two render-target bits reach EVERY signed-normalized format, one-, two- and // four-channel included. They used to be granted to GL_RGB16_SNORM alone, which left the - // other seven with no colour-renderable fallback at all on a driver without + // other seven with no color-renderable fallback at all on a driver without // EXT_render_snorm: an R8_SNORM or R16_SNORM attachment (what KHR-GL4x.texture_swizzle // renders into for every SNORM source format) got no substitute, so the ES framebuffer was // incomplete, the draw landed nowhere and the readback fell through to the never-written @@ -94,7 +94,7 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { namespace { // The four-channel sibling a three-channel format is widened to when the target has to - // stay colour-renderable, together with the transfer pair that describes client data for + // stay color-renderable, together with the transfer pair that describes client data for // it. Kept in one place because all three of NormalizePixelFormat's switches have to agree: // reporting the widened storage but the original three-channel base format emitted // inconsistent triples such as (GL_RGBA16F, GL_RGB, GL_BYTE), which is @@ -129,7 +129,7 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { ? ThreeChannelWidening{GL_RGBA32F, GL_RGBA, GL_FLOAT} : ThreeChannelWidening{GL_RGBA16_SNORM, GL_RGBA, GL_SHORT}; // Unsigned-normalized 16-bit (and the legacy 10/12-bit formats stored as RGB16): - // GL_RGB32F is a legal ES texture format but is not colour-renderable either. + // GL_RGB32F is a legal ES texture format but is not color-renderable either. case GL_RGB16: case GL_RGB10: case GL_RGB12: @@ -143,7 +143,7 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { // refused outright (KHR-GL4x.texture_view.view_classes). Against GL_RGBA16 // the whole class lands on ES's 64-bit class and every channel reinterprets // bit-exactly. EXT_texture_norm16 - the absence of which is what NoNorm16 - // means - is also what makes GL_RGBA16 colour-renderable, so the two + // means - is also what makes GL_RGBA16 color-renderable, so the two // questions have one answer. return (options & PixelFormatNormalizeOptionBit::NoNorm16) ? ThreeChannelWidening{GL_RGBA32F, GL_RGBA, GL_FLOAT} @@ -153,7 +153,7 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { return {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}; case GL_RGB32F: return {GL_RGBA32F, GL_RGBA, GL_FLOAT}; - // sRGB: GL_SRGB8_ALPHA8 keeps the sRGB encoding of the colour channels and stores + // sRGB: GL_SRGB8_ALPHA8 keeps the sRGB encoding of the color channels and stores // the added alpha linearly, which is exactly the three-channel format's semantics. case GL_SRGB8: return {GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE}; @@ -556,7 +556,7 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { // frontend's validator demands (Validators.cpp: // "STENCIL_INDEX requires a stencil-only internal format") and the same one the // stencil readback path hands the driver. The unsized spelling is here for the same - // reason the unsized depth and colour formats are: it resolves to this storage. + // reason the unsized depth and color formats are: it resolves to this storage. case GL_STENCIL_INDEX8: case GL_STENCIL_INDEX: *outFormat = GL_STENCIL_INDEX; @@ -803,7 +803,7 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { } // Applied last, over whatever the three switches above chose: widening a three-channel - // format to keep a colour attachment renderable outranks every other fallback, because + // format to keep a color attachment renderable outranks every other fallback, because // the others all pick a three-channel storage the driver still refuses to render to // (GL_RGB8_SNORM -> GL_RGB16F under NoSnorm8, GL_RGB16 -> GL_RGB32F under NoNorm16). // All three outputs move together: reporting the widened storage while leaving the diff --git a/MobileGL/MG_Util/Texture/TextureFormatProcessor.h b/MobileGL/MG_Util/Texture/TextureFormatProcessor.h index c323009b..3b23d85f 100644 --- a/MobileGL/MG_Util/Texture/TextureFormatProcessor.h +++ b/MobileGL/MG_Util/Texture/TextureFormatProcessor.h @@ -18,9 +18,9 @@ namespace MobileGL { NoDepthComponent32 = 1 << 4, NoRGBA8Snorm = 1 << 5, NoRGB16Snorm = 1 << 6, - // The target must be colour-renderable and ES has no renderable three-channel + // The target must be color-renderable and ES has no renderable three-channel // form of the requested format, so it has to be widened to the four-channel one. - // Set for any colour-attachable target whose native three-channel form the driver + // Set for any color-attachable target whose native three-channel form the driver // refused to render to (multisample storage always, since ES has no three-channel // multisample format at all; every other target only after its native probe failed). // The widening is visible to every transfer path, so it also retargets the (format, @@ -29,7 +29,7 @@ namespace MobileGL { // three-channel client data with an alpha of 1.0, and sampling/readback has to hide // the added alpha again (BackendTextureFormatAddsAlpha). NoThreeChannelRenderTarget = 1 << 7, - // A 16-bit signed-normalized image has to back a colour attachment, and the driver cannot + // A 16-bit signed-normalized image has to back a color attachment, and the driver cannot // render to the signed-normalized encoding itself: that needs both EXT_texture_norm16 and // EXT_render_snorm, and without either one an R16_SNORM / RG16_SNORM / RGB16_SNORM / // RGBA16_SNORM attachment is texture-only, so the framebuffer is never complete and the @@ -40,7 +40,7 @@ namespace MobileGL { // 65535 channel values bit for bit. NoSnorm16RenderTarget = 1 << 8, // The 8-bit twin of the bit above: without EXT_render_snorm an R8_SNORM / RG8_SNORM / - // RGB8_SNORM / RGBA8_SNORM colour attachment is not renderable either. Here a half float + // RGB8_SNORM / RGBA8_SNORM color attachment is not renderable either. Here a half float // IS exact - every value in [-127, 127] divided by 127 round-trips through a half - so the // substitute matches what the always-on GL_RGBA8_SNORM fallback already picks. NoSnorm8RenderTarget = 1 << 9, diff --git a/MobileGL/MG_Util/Types.h b/MobileGL/MG_Util/Types.h index 8e7e82b4..61cb4457 100644 --- a/MobileGL/MG_Util/Types.h +++ b/MobileGL/MG_Util/Types.h @@ -74,7 +74,7 @@ namespace MobileGL { // Open addressing with robin-hood probing. Any insert, emplace, operator[], // reserve or rehash invalidates every iterator, reference and pointer into the // map - and NOT only by rehashing: robin-hood insertion swaps the entry being - // placed against the occupant whenever it has travelled further from its desired + // placed against the occupant whenever it has traveled further from its desired // position, so an insert well under the load factor still relocates entries. // Erase relocates too, and less obviously - deletion shifts the rest of the probe // cluster backwards, so erasing one key can move a DIFFERENT key's element. @@ -94,7 +94,7 @@ namespace MobileGL { // // T must be move-ASSIGNABLE, not merely move-constructible: robin-hood probing // swaps the entry being inserted against the one already in the slot whenever it - // has travelled further from its desired position. A move-only RAII type that + // has traveled further from its desired position. A move-only RAII type that // declares a destructor gets no implicit move assignment, so it needs an explicit // one or the table will not instantiate (see RenderPassEntry). template , class KeyEqual = std::equal_to, diff --git a/README.md b/README.md index f36c1453..a37bb9bf 100644 --- a/README.md +++ b/README.md @@ -174,11 +174,11 @@ MobileGL supports runtime configuration via environment variables. | `MOBILEGL_FRAMES_IN_FLIGHT` | How many frames may be queued ahead of the GPU (Magma: its frame contexts; Espryt: how far presents may run ahead). The old name `MOBILEGL_MAGMA_FRAMESINFLIGHT` still works but is deprecated. | Integer `1`–`64` | `3` | | `MOBILEGL_MAGMA_MAX_DRAWS_PER_COMMAND_BUFFER` | Draws and dispatches Magma records into one command buffer before it submits the buffer mid-frame and continues on a fresh one. `0` never splits. | Integer `0`–`16777216` | `16384` | | `MOBILEGL_MAGMA_DESCRIPTOR_TRIM_FRAMES` | Frames a frame slot's descriptor pools must stay under a quarter full before Magma frees the slot's cached descriptor sets and grown pools. `0` never trims. | Integer `0`–`1048576` | `120` | -| `MOBILEGL_MAGMA_EXTRA_SWAPCHAIN_IMAGES` | Swapchain images Magma asks for beyond the surface's minimum, capped at its maximum. More images delay the reuse of the window buffer the display has just released, so fewer frames wait for its release; each costs a full-size colour buffer and a depth/stencil buffer. | Integer `0`–`16` | `0` | +| `MOBILEGL_MAGMA_EXTRA_SWAPCHAIN_IMAGES` | Swapchain images Magma asks for beyond the surface's minimum, capped at its maximum. More images delay the reuse of the window buffer the display has just released, so fewer frames wait for its release; each costs a full-size color buffer and a depth/stencil buffer. | Integer `0`–`16` | `0` | | `MOBILEGL_ESPRYT_AVOID_SAMPLER_MIPMAP_MIN_FILTER` | Avoid sampler mipmap minification filters. | `0`, `1` | `0` | | `MOBILEGL_COHERENT_AS_FLUSH` | Treat persistent `GL_MAP_FLUSH_EXPLICIT_BIT` maps as coherent (app-compat for engines like Flywheel that never flush them). | `0`, `1` | `0` | | `MOBILEGL_ESPRYT_FORCE_DS_READBACK_EMULATION` | Always emulate depth/stencil `glReadPixels`/`glGetTexImage` by shader sampling on Espryt, instead of using the driver's own depth/stencil readback where it has one. | `0`, `1` | `0` | -| `MOBILEGL_YUV_DRIVER_CONVERSION` | Espryt: convert YUV images with the driver's external-sampler conversion (its own colour space) instead of `GL_EXT_YUV_target` with the import's `EGL_YUV_COLOR_SPACE_HINT_EXT` / `EGL_SAMPLE_RANGE_HINT_EXT`. | `0`, `1` | `0` | +| `MOBILEGL_YUV_DRIVER_CONVERSION` | Espryt: convert YUV images with the driver's external-sampler conversion (its own color space) instead of `GL_EXT_YUV_target` with the import's `EGL_YUV_COLOR_SPACE_HINT_EXT` / `EGL_SAMPLE_RANGE_HINT_EXT`. | `0`, `1` | `0` | | `MOBILEGL_SERVER_FRAME_STATS` | Log one `P65ServerFrame` timing line per presented frame on the server (apply vs. wall time, socket read rate). On Android also `debug.mobilegl.server_frame_stats`. | `0`, `1` | `0` | | `VK_ICD_FILENAMES` | Select the Vulkan ICD used by the Vulkan loader. | Path to an ICD JSON file | Loader default | diff --git a/docs/Disaggregated/ARCHITECTURE.md b/docs/Disaggregated/ARCHITECTURE.md index 5a368d4a..de91545b 100644 --- a/docs/Disaggregated/ARCHITECTURE.md +++ b/docs/Disaggregated/ARCHITECTURE.md @@ -1,36 +1,36 @@ -# 设计与架构(索引) +# Design and architecture (index) -> 这一页只有设计要点和章节去向;每一部分的完整设计在 [`design/`](design/)。章节编号 §1–§17、附 A / B 沿用至今,代码注释里写的 `ARCHITECTURE.md §N` 按下表找到对应文件。各阶段的 wire 契约原文见 git 历史,与设计文字冲突时以更新的契约为准。 +> This page holds only the design points and where each chapter lives; the full design of each part is in [`design/`](design/). Section numbers §1–§17 and appendices A / B are still in use; `ARCHITECTURE.md §N` written in code comments maps to a file in the table below. The original wire contracts for each phase are in git history; where they conflict with the design text, the newer contract wins. -## 一句话 +## In one sentence -后端本来就维护着一台贴着 GLES / Vulkan 的状态机,缺的只是"我被告知了什么"。MGPipe 让前端在每条做事的命令之前,把状态变化以**记录**的形式推给后端;后端只认这些记录、不读前端内存,所以两者之间可以隔一个线程、一个进程或一根网线。 +The backend already maintains a state machine that tracks GLES / Vulkan; all that is missing is an explicit statement of "what I was told". MGPipe has the frontend push state changes to the backend as **records** before each command that does work; the backend recognizes only these records and does not read frontend memory, so a thread, a process, or a network cable can sit between the two. -## 设计要点 +## Key design points -1. **一份调用目录生成一切**:`PipeCalls.def` 一行一个调用,线上编号就是行序、只追加;两张函数指针表、编解码、校验器都由它生成。 -2. **对象用句柄 `{slot, gen}` 寻址**:由前端分配,后端从不回传,所以创建对象不需要往返。 -3. **状态在命令之前一次性推送**,不是每个 GL setter 都推;整块数据过线、按内容去重,没变就不发。 -4. **同一份后端实现,三种拓扑**:单线程直调 / 同进程两线程 / 两个进程(可跨机)。 -5. **反向消息是具名回调**(错误、GPU 写回、窗口尺寸……),走一条与命令同样有序的事件通道。 -6. **着色器以 SPIR-V + 反射信息过线**:编译在前端,转译与按状态特化在后端。 -7. **传输分两层**:控制面(握手、EGL 控制)与数据面(命令、批量数据),各自可选本机共享内存或字节流 / TCP,可以混搭;上层代码不区分链路种类。 -8. **client 发完就走(run-ahead)**:只有需要答案的命令才等;靠 present 配额限速。 -9. **出错不崩**:server 崩溃或断线时 client 进入"设备丢失"状态;外来连接要令牌,畸形输入被拒绝而不是让 server 退出。 -10. **可证明的迁移**:每个门都必须能变红;单进程构建的二进制在整个拆分过程中逐字节不变(G1)。 +1. **One call catalog generates everything**: `PipeCalls.def` has one call per line; the wire number is the line order and is append-only; the two function pointer tables, the codec, and the validator are all generated from it. +2. **Objects are addressed by handle `{slot, gen}`**: allocated by the frontend, never sent back by the backend, so creating an object needs no round trip. +3. **State is pushed once before a command**, not by every GL setter; whole blocks cross the wire and are deduplicated by content, and unchanged data is not sent. +4. **One backend implementation, three topologies**: direct calls in one thread / two threads in one process / two processes (possibly across machines). +5. **Reverse messages are named callbacks** (errors, GPU writeback, window size…), over an event channel ordered like commands. +6. **Shaders cross the wire as SPIR-V + reflection information**: compiled in the frontend, translated and specialized by state in the backend. +7. **The transport has two layers**: control plane (handshake, EGL control) and data plane (commands, bulk data), each independently choosing local shared memory or a byte stream / TCP, and they can be mixed; upper-layer code does not distinguish link types. +8. **The client runs ahead (run-ahead)**: only commands that need an answer wait; present credit paces it. +9. **Errors do not crash**: when the server crashes or disconnects, the client enters a "device lost" state; external connections need a token, and malformed input is rejected rather than making the server exit. +10. **Provable migration**: every gate must be able to turn red; the monolith build's binary stays byte-identical throughout the split (G1). -## 章节去向 +## Where the chapters live -| § | 内容 | 文件 | +| § | Content | File | |---|---|---| -| 1–2 | 边界:两张表、三种拓扑;对象模型:句柄、两种代数、CSO | [`design/01-boundary-and-objects.md`](design/01-boundary-and-objects.md) | -| 3–4 | 调用目录、生成器 G1–G8、能力位;记录与 payload 格式 | [`design/02-catalogue-and-records.md`](design/02-catalogue-and-records.md) | -| 5–7 | 前端 tracker(何时推、推什么、怎么去重);纹理上传;着色器 | [`design/03-frontend.md`](design/03-frontend.md) | -| 8 | 反向通道:七个回调、有序性、错误与 ack、纹理重铸(server 本地,无拉取)、XFB | [`design/04-reverse-channel.md`](design/04-reverse-channel.md) | -| 9–10 | 后端改造(`PipeInputs`、memo 重键、A/B 臂);server 侧 applier | [`design/05-backend-and-server.md`](design/05-backend-and-server.md) | -| 11 | 传输:共享段、环、门铃、控制面、背压、等待规则、事件、两根轴 | [`design/06-transport.md`](design/06-transport.md) | -| 12–13 | persistent map 与大缓冲采纳;回读、往返清单、五部分验证门 | [`design/07-memory-readback-verification.md`](design/07-memory-readback-verification.md) | -| 14–15 | 帧节奏与线程;进程、握手、EGL、Android(含上屏 server)、崩溃处理 | [`design/08-runtime-and-platform.md`](design/08-runtime-and-platform.md) | -| 16、附 A、附 B | 源码目录与构建选项;全部开关;边界计数器 | [`design/09-build-switches-counters.md`](design/09-build-switches-counters.md) | -| 17 | 各阶段落地时的形状与仍生效的规则(原文见 git 历史) | [`design/10-phase-shapes.md`](design/10-phase-shapes.md) | -| — | 状态归属:多 session / 多 context / share group(anland 统一 server 前置) | [`design/11-state-ownership.md`](design/11-state-ownership.md) | +| 1–2 | Boundary: two tables, three topologies; object model: handles, two generations, CSO | [`design/01-boundary-and-objects.md`](design/01-boundary-and-objects.md) | +| 3–4 | Call catalog, generators G1–G8, capability bits; record and payload format | [`design/02-catalogue-and-records.md`](design/02-catalogue-and-records.md) | +| 5–7 | Frontend tracker (when to push, what to push, how to deduplicate); texture upload; shaders | [`design/03-frontend.md`](design/03-frontend.md) | +| 8 | Reverse channel: seven callbacks, ordering, errors and ack, texture re-mint (server-local, no pull), XFB | [`design/04-reverse-channel.md`](design/04-reverse-channel.md) | +| 9–10 | Backend rework (`PipeInputs`, memo re-key, A/B arms); server-side applier | [`design/05-backend-and-server.md`](design/05-backend-and-server.md) | +| 11 | Transport: shared segment, ring, doorbell, control plane, backpressure, wait rules, events, two axes | [`design/06-transport.md`](design/06-transport.md) | +| 12–13 | Persistent map and large-buffer adoption; readback, round-trip list, five-part verification gate | [`design/07-memory-readback-verification.md`](design/07-memory-readback-verification.md) | +| 14–15 | Frame pacing and threads; process, handshake, EGL, Android (including the on-screen presentation server), crash handling | [`design/08-runtime-and-platform.md`](design/08-runtime-and-platform.md) | +| 16, Appendix A, Appendix B | Source directory and build options; all switches; boundary counters | [`design/09-build-switches-counters.md`](design/09-build-switches-counters.md) | +| 17 | The shape each phase landed in and the rules still in force (originals in git history) | [`design/10-phase-shapes.md`](design/10-phase-shapes.md) | +| — | State ownership: multiple sessions / multiple contexts / share groups (prerequisite for the anland unified server) | [`design/11-state-ownership.md`](design/11-state-ownership.md) | diff --git a/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md b/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md index f97df837..add22bc2 100644 --- a/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md +++ b/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md @@ -1,26 +1,26 @@ -# 当前阶段:P13 已收官(2026-10-07);下一阶段 P14 +# Current phase: P13 closed (2026-10-07); next phase P14 -> **更新 2026-10-07**。这一页只有摘要;计划与裁定见 git 历史。上一阶段 P8 于 09-30 收官。 +> **Update 2026-10-07**. This page holds only a summary; plans and rulings are in git history. The previous phase P8 closed on 09-30. -## 目标 +## Goal -退役 pull 路径:单进程(FCL 内嵌库)也走 P8 修好的记录臂,删掉旧的「后端直接读前端」路径与它的全部编译期 / 运行期开关。 +Retire the pull path: the monolith (the library embedded in FCL) also runs on the record arm fixed in P8, and the old "backend reads the frontend directly" path and all its compile-time / run-time switches are deleted. -## 完成情况 +## Completion -| 项 | 状态 | +| Item | Status | |---|---| -| W1 CI 地基(skip 普查、零 `MG_Remote` 符号检查、运行期形态证明) | ✅ | -| W2–W3 默认翻转与去宏(`MOBILEGL_PIPE_PUSH` / `LEGACY_MEMOS` 删除,位 0–13 固定开) | ✅ | -| W4–W5 单进程换到记录臂,记录臂移出 `MG_Remote` | ✅ | -| W6 删后端的前端对象臂(Espryt / Magma),`# P13` 债务清零 | ✅ | -| W7 七个 OBJECT 模块 + server-only 链接检查 | ✅ | -| W8 recorder 金标(首跑抓到并修掉两个单进程推送内容缺陷) | ✅ | -| W9 缓存容量重调 | 移到 P13 之后的性能轮(用户 10-07) | -| W10 文档与收官 | ✅;FCL 真机两后端冒烟通过 | +| W1 CI foundation (skip census, zero `MG_Remote` symbol check, runtime shape proof) | ✅ | +| W2–W3 default flip and macro removal (`MOBILEGL_PIPE_PUSH` / `LEGACY_MEMOS` deleted, bits 0–13 fixed on) | ✅ | +| W4–W5 the monolith switches to the record arm, the record arm moves out of `MG_Remote` | ✅ | +| W6 delete the backend's frontend-object arm (Espryt / Magma), `# P13` debts zeroed | ✅ | +| W7 seven OBJECT modules + server-only link check | ✅ | +| W8 recorder golden (the first run caught and fixed two monolith push-content defects) | ✅ | +| W9 cache capacity re-tuning | moved to the performance round after P13 (user 10-07) | +| W10 documentation and close-out | ✅; FCL on-device smoke passes on both backends | -## 下一步 +## Next steps -**P14**:状态归属(同进程多 session / 多 context / share group),设计见 [`design/11-state-ownership.md`](design/11-state-ownership.md)。性能轮(基线 `dev` 构建,定频,FCL MC + anland glmark2,两后端)也排在 P13 之后。 +**P14**: state ownership (multiple sessions / multiple contexts / share groups in one process), design in [`design/11-state-ownership.md`](design/11-state-ownership.md). The performance round (baseline `dev` build, pinned clocks, FCL MC + anland glmark2, both backends) is also queued after P13. -**待用户决策**:[`DEBTS.md`](DEBTS.md) 中「需裁定」各项;FCL 无声死亡留给用户(细节见 git 历史)。 +**Awaiting user decisions**: the "needs a ruling" entries in [`DEBTS.md`](DEBTS.md); FCL's silent death is left to the user (details in git history). diff --git a/docs/Disaggregated/DEBTS.md b/docs/Disaggregated/DEBTS.md index 8373b052..b23a7a12 100644 --- a/docs/Disaggregated/DEBTS.md +++ b/docs/Disaggregated/DEBTS.md @@ -1,52 +1,52 @@ -# 仍开放的债务(跨阶段) +# Still-open debts (cross-phase) -> **2026-10-07(P14 收官)**:W9 关闭(读数,见下);ID-P13-2(Magma monolith)更新为 trace 已基本追平、FCL 仍差的现状;新增三行:Espryt monolith 记录臂的逐项构成与结构原因、driver 项的 cache 压力推断、测过未做的前端变更 epoch 快路径。下一阶段是 draw-packet 缓存重设计。 +> **2026-10-07 (P14 close)**: W9 closed (readout, see below); ID-P13-2 (Magma monolith) updated to the current state where traces are largely caught up but FCL still trails; three rows added: the per-item composition and structural cause of the Espryt monolith record arm, the cache-pressure inference for the driver item, and the tested-but-not-done frontend change-epoch fast path. The next phase is the draw-packet cache redesign. > -> **2026-10-07(P13 收官)关闭三行**:ID-P8-13(9 条 monolith 缺陷——monolith 换到记录臂后对应 monolith 登记在集成车道上全过,旧的 monolith 前端臂在 W6 删除)、ID-P8-14(`SyncClientSideVertexArraysForIndirectFetch` 的整 buffer 回读与 Magma monolith 深度 mip 的 view 类型都属于已删的 monolith 前端臂)、`MOBILEGL_PIPE_TEXEL_RETAIN_MB`(W3b 随 pull 构建删除)。新增两行:W9 缓存容量重调与 Magma monolith 性能,都排在 P13 之后的性能轮,基线是 `dev` 构建。 +> **2026-10-07 (P13 close), three rows closed**: ID-P8-13 (9 monolith defects — after the monolith moved to the record arm, the corresponding monolith registrations all pass on the integration lane; the old monolith frontend arm was deleted in W6), ID-P8-14 (the whole-buffer readback in `SyncClientSideVertexArraysForIndirectFetch` and the depth mip view type in Magma monolith both belong to the deleted monolith frontend arm), `MOBILEGL_PIPE_TEXEL_RETAIN_MB` (W3b deleted with the pull build). Two rows added: W9 cache capacity re-tuning and Magma monolith performance, both queued for the performance round after P13, with the `dev` build as baseline. > -> 路线图只列"有债务、看这里"。每条写明去向;已关闭的历史债与当时的完整债务表见 git 历史。开放问题另见 [`OPEN-QUESTIONS.md`](OPEN-QUESTIONS.md)。更新:2026-09-30(P8 第二波;按债务审查重排。同日:create-indirect 换成派生 fixture `minecraft-1.21.1-neoforge-create-indirect-in-world-align1024`(不是原抓取,16 字节对齐的 SSBO 范围绑定挪到 1024 对齐),ID-P8-14、ID-P8-19 两条关闭——红米两后端 monolith / spawn 全过,Magma spawn 不再丢设备)。去向「需裁定」= 等用户定;「可进行」= 随时可开的小修,不依赖别的阶段。 +> The roadmap lists only "there are debts, look here". Each entry states its disposition; closed historical debts and the full debt table of that time are in git history. Open questions are in [`OPEN-QUESTIONS.md`](OPEN-QUESTIONS.md). Updated: 2026-09-30 (P8 second wave; reordered per the debt review. Same day: create-indirect switched to the derived fixture `minecraft-1.21.1-neoforge-create-indirect-in-world-align1024` (not the original capture; the 16-byte-aligned SSBO range bindings moved to 1024 alignment), ID-P8-14 and ID-P8-19 closed — Redmi passes on both backends for monolith / spawn, and Magma spawn no longer loses the device). Disposition "needs a ruling" = waiting for the user to decide; "can proceed" = a small fix that can start anytime and does not depend on another phase. -| 债务 | 去向 | +| Debt | Disposition | |---|---| -| CI 覆盖:`test.yml` / `apk.yml` 按分支名(`feat/disaggregated`、`codex/fix-github-ci`)切 `MOBILEGL_CI_DISAGGREGATED` 与车道(本次核对 `test.yml` 14 处、`apk.yml` 4 处);pull 构建只有 G1 与 monolith 对照,没有集成测试门(`TextureRemintPullScenario` 在 pull 上自 P9 红到 P11 M 才修);合入 `dev` 后 inproc 验收与 APK split 两臂随分支名关掉,build-linux-split / integration-split / retrace-split 无条件 | 需裁定:合入前是否加 pull 集成车道;合入 `dev` 后各车道的触发条件(顺带删 `feat/disaggregated` 触发器) | -| P9 转出:`TCP_USER_TIMEOUT` = 5000 ms——client 停读控制超过 5 s 且有待发日志字节时内核断开连接;`PublishSessionFault` 的阻塞写对停读的 client 最多等同样 5 s(ID-P9-10)。风险场景:FCL 退后台暂停 + 跨机 TCP | 需裁定:建议调到几十秒、`PublishSessionFault` 改有界写;取值由用户定 | -| P11 转出(B0 F1):HyperOS 熄屏冻结 server app 整个 uid。B1 已靠用户设置解决(server app 与 client 所在 app 电池都设「无限制」,ID-P11-16);剩 FCL 同机用法的保活 | 需裁定:只写须知 / app 内检测省电策略并引导 / 不管 | -| P11 转出(B2):T0 只在红米一台 Adreno 上实测;Mali 等只有 spike B 的 shell 域证据(server 自测会在不支持的设备上退回 T2)。「respecify 时立即释放导入」的变异在 Espryt 上不红(驱动大概自己持有引用,未核实),带 fence 的释放保留 | 需裁定(受设备规矩所限):开一台 Mali 复测,或长期接受自测退回 | -| P11 转出(B1):外部 client 的 apply 线程策略只在红米一台(两大核)上量过;Magma openra 两个数据面都卡在 server(约 285 fps),共享内存无收益 | 同上一行 | -| P12 未做:TLS(开放问题 21 当时「令牌够,TLS 留作 P12 开放项」;P12 已收官) | 需裁定:正式放弃,或继续留作开放项 | -| `MOBILEGL_IPC_IDLE_EXIT_S` 未解析(client EOF 时 server 已即时退出) | 需裁定:建议废弃;点头后删 `design/09-build-switches-counters.md:67` 与 `Config.h` 注释等处 | -| P10 转出:`GL_ARB_gpu_shader_fp64` 按 server 的 `MOBILEGL_ADVERTISE_FP64` 宣告,fp64 收窄却在 client 的编译里;tcp 下 server 环境不同时两者不一致(同类的 `GL_KHR_parallel_shader_compile` 已修,做法见 `CapsMirror.cpp:72-101`,ID-P10-10) | 可进行(小修) | -| P11 转出:client 与 server 共用日志前缀时,client 以 `"w"` 打开 `.server.log` 写转发来的 server 日志(`MobileGL/MG_Util/Debug/Log.cpp:89`),截断 server 自己的文件;同机两个进程用同一前缀时同样互相截断 | 可进行(小修) | -| P11 转出(B1):会话位被慢启动程序占着时,第二个 client 若 2 s 内发 Hello 得具名 `Refuse{Busy}`,更慢的只见发送失败(那条路径不读待发的拒绝);已写进契约 | 可进行(小修) | -| P11 转出(B1):会话启动失败后 client 还多报一个误导性的 `Fatal{CapsBeforeFirstSnapshot}`(`CapsMirror.cpp:247`,早于 B1,helper 用户每次被拒都会看到) | 可进行(小修) | -| P11 转出(B2):handle 臂的 CPU 读者读采纳 / T0 映射前先落排队常驻写——split 半已由 P8-C 实现(`SplitHostBytesForCpuRead` 的 T0 臂:落写 + `glFinish`,ID-P8-9),但主机无 T0、未能证红 | 需设备验证(红米 Android 集成测试 + static-peek) | -| P11 转出(B2):server 准了 T0 而 client 选了 T2 时,每个存储的 `map_persistent` 等 2 s 再具名拒绝(产品里 grant 与 caps 一致,只在变异下见过) | 可进行(小修:每会话一个「client 不要 T0」提示) | -| P9 转出:Espryt 重铸保留路径上 framebuffer clear 后 `imageLoad` 偶读旧值(主机 3/30,加 barrier 后 0/30;`TextureRemintPullScenario` case C 暂钉 barrier),疑 llvmpipe(ID-P9-11);P11 合并 dev 后 push 单进程臂上也见过一次,`ImageBindableRemintScenario` 同样钉 barrier(ID-P11-6) | 可进行(在红米上不加 barrier 归因) | -| P8 转出(D):应用省略 `glMemoryBarrier` 时,两臂在计算写与顶点着色器读之间都没有依赖(GL 未定义,但真实应用依赖它);D 的每轮屏障在真机上的开销未测;create-indirect(现为派生的 `minecraft-1.21.1-neoforge-create-indirect-in-world-align1024`,内容相同)验证不了这两件事(ID-P8-14),需要一个「计算写命令、无应用屏障、不重写」的 fixture | 待归因(需新 fixture) | -| P8 转出(E):driver-written 标按整张纹理打(`GenerateMipmap` 也打),驱动拒读时连基级也具名拒绝,偏保守;跨格式拷贝 store 不跟随;拒绝仍是会话 Fatal(要改回包状态才能答 `GL_INVALID_OPERATION`) | 小修(按 level 打标);其余按需 | -| P8 转出(B):`PipeCalls.def:260` `GenerateMipmap` 仍是 `kWaitApplied`,裁定 14 的理由(CPU 滤波碰 client 影子)已不成立,可改 `kWaitNone` | 性能工作(协议行为变更,需单独裁定) | -| P8 转出(C):server SSBO 标记过近似(窗口内每个绑定的 SSBO 都标);一个留在 SSBO 绑定上又当 restart EBO 用的 buffer 每次 draw 都回读 | 性能工作 | -| P13 转出(ID-P13-2,P14 更新):Magma monolith 记录臂对 dev(pull)——trace 上已基本追平:rd12 83.8 对 87.0 fps(−4%),openra 747 对 293(dev 在那里等 GPU);P14 最大一项是 `553eb86d`(纹理层上传不再在 CPU 上等 GPU 排空,rd12 70→83)。但 **FCL MC 上仍差**:monolith 171 对 dev 232(−26%),inproc 195;呈现线程 CPU 只占约 2.8 / 5.8 ms 帧,其余是等待——与 trace 不同的另一处等待 | 下一阶段第一项:FCL Magma monolith 做 off-CPU profile(`--trace-offcpu`,同找到上传等待的方法;P14 收官时两次采集都没抓到游戏帧),找出那 3 ms 等待;数字见 git 历史 | -| ~~P13 转出(W9):缓存容量重调~~ **P14 关闭(读数)**:`MOBILEGL_PIPE_STATS` 在 rd12 / openra 上 render-state CSO 稳态每帧新铸 0 个,Magma 管线 memo 命中 99.0% / 92.7%,没有缓存抖动,P8 容量保留 | 已关闭(W9 节,见 git 历史) | -| P14 转出:Espryt monolith 记录臂对 dev(pull)rd12 91.1 对 115.2 fps(−21%);FCL MC 198 对 229(−13%)。渲染线程每帧 CPU 11.56 对 9.07 ms:client half +1.39(validate 0.92:EmitGlobalConstants 0.17、EmitVertexElements 0.13、Tracker::Update 0.12、CopyField 0.10、validate 自身 0.10、EmitVertexBuffers 0.07;verb port 约 0.2)、backend +0.45(SyncNeccessaryTextures +0.14、SyncNeccessaryBuffers +0.08、AdoptUnchangedBufferSets +0.09、BindCurrentProgramWithResources +0.07、SyncCurrentProgramByHandle +0.05)、driver +0.33、applier +0.07。每项都在帧时间 2% 以下;合起来是记录臂的结构成本:pull 的后端在 draw 时按指针读前端对象,push 要检测变化(tracker)、序列化(emitter、uniform span)、应用(applier)、再由后端按句柄经 slot 表重新解析,并且因为后端看不到前端脏位而对每个绑定对象做 clean 检查——每步每 draw 几十 ns、各自是不相干的冷 cache 行,乘以 1471 draw/帧 | 下一阶段:per-(VAO, program) draw-packet 缓存(设计草稿(见 git 历史),估计 rd12 Espryt monolith 回收 1.0–1.6 ms/帧,约 91→100–106 fps);先只做 client half 原型量 | -| P14 转出:Espryt monolith 的 driver 项 +0.33 ms/帧(2.9%),全在 `glDrawElements` 内部,GL 调用组合与 dev 相同。`simpleperf stat`(整次运行、渲染线程):feat 比 dev 多执行 16.6% 指令、L1D refill 多 56%、L2D 多 23%(IPC 3.73 对 3.86)。推断:记录臂每 draw 更大的工作集(record、applier 状态、slot 表、twin)把驱动的状态挤出 cache——这是计数器推断,没有在驱动内部测量 | 随 draw-packet 缓存一起验证:落地前后量 L1D refill 与 driver ms/帧;如果 driver 项不降,推断不成立,再单独查 | -| P14 转出(测过未做):Tracker / residual 的前端变更 epoch 快路径——在每个 `DECLARE_GL_FUNCTION_END` 入口(除 draw、`glBindVertexArray`、浮点 `glUniform*` 外)以及手写入口和 EGL 入口里 bump 一个上下文 epoch;epoch 未动时 validate 只重算 VAO / program 派生的 shutter(上限约 0.07 ms),再经审计哪些 residual 字段依赖 VAO / program 绑定后跳过 residual copy(合计 0.15–0.25 ms,1.5–2%) | 各自低于 2% 门槛,且漏 bump 一个入口就渲染陈旧状态;并入 draw-packet 设计(其 §3 的上下文 epoch 就是它),不单独做 | -| P13 转出(FCL 浸泡,用户裁定:FCL 暂不改、MobileGL 不做规避):FCL game process can die silently (exit SIGNALED status=34, SIGRTMIN+2): the JVM signal reset after renderer selection drops libcore's AsynchronousCloseMonitor handler, and FCL's okhttp/Okio watchdog then kills the process; renderer-independent (reproduced on P12 and P13 libraries, both backends; untested with other renderers)。浸泡:P13 库 30 次(Magma 22 / Espryt 8)死 18 次、P12 库 10 次死 2 次;P12 / P13 逐次交替的对照(同场景同网络时段)P12 4/10、P13 2/10,时间线(`Renderer:` 行到 MobileGL 首行约 6.2 s、晚死固定在其后约 9.4 s)两库相同,无证据表明 MobileGL 拉高概率;全部 status=34,无 tombstone、无 kgsl;证据与机理见 git 历史 | fix belongs in FCL (save/restore libcore's SIGRTMIN+2 sigaction around JVM creation); left for the user | -| P8 转出(MD):dev 的 `RingAllocateSlow` 在出错的上下文上无上限地排水(设备上挂在 `glFinish`) | 小修(dev) | -| P8 转出:`LogForwardChannel.APeerThatStopsReadingCostsWarnLinesNotTheCallersTime` 在负载下超时(两次),单跑必过 | 小修(放宽时限或隔离) | -| P8 转出(SV):`gen_pipe_dirty_surface.py` 扫描集成测试源,测试成员名与 GLContext 成员同名(如 `m_parameters`)会静默弄坏它的自检;`.Mip3DValidation.` 在没装校验层的车道上是失败不是跳过 | 小修 / CI 记录 | -| P8 转出(MF):两条 flush 阶梯附近几处注释仍写旧的冻结 / 钉住提交(`5cb826b0`、`3e298c9a`) | 文档小修 | -| P8-0 转出:设备上基线就有的 SSIM < 0.99——1.21.11-main-menu(Espryt 0.890、Magma 0.165)、derivative-main(Espryt 0.851);两臂都有 | 待归因 | -| P12 未做:D8 窗口种类白名单——X11 / MetalLayer / Win32Hwnd / None 仍被接受(`SurfaceOpCodec.cpp:138-141`),`HandleFromToken` 把 token 强转为指针(`ServerLoop.cpp:1228`,经 `UnpackWindowHandle`;下游是否交给 EGL 未追到底) | 可进行(Ph 类小修) | -| P12 未做:修后的横屏 server 窗口未重测 | 可进行(红米只读检查) | -| P11 转出(M2,给 dev):dev 的 `DirectVulkan.SplitRecording.` 车道没有 `RESOURCE_LOCK`、其用例读字面日志路径——`-j` 下可能互相截断;P11 线的副本已修(Magma 空 uniform 的重复修复已在 ID-P8-17 合成一条) | 下次向 dev 回流时带上 | -| P11 转出(M2):超过 stage 分块预算的大层按分片发出,没有写入框覆盖的分片仍带整框(server 要靠它拼层图),会把影子盖到 GPU 写过的地方;修法要一个两个 server 都跳过的「只定位」区域写法,控制协议修订 +1(split 专属,早于 P11) | 小包或 P8 | -| P11 转出(M2):上传仍有两种有损形状,各记一次日志——一层的精确写入框超过 4096 个时按存储的矩形表覆盖发出;applier 一个条目累计超过 4096 个区域时并成并集框。纹理带 GPU 写时两者都会把影子盖进空隙 | 小修,无触发报告 | -| P10 转出(性能):设备上 tcp loopback 的 rd12 每帧 19.4 ms 中 ~11.2 ms 是生产者在 stream 传输里的停车(发送 + 环 / stage / ack 等待),credit 等待只有 ~0.2 ms(见 git 历史 §2,ID-P10-13) | 路线图推完后的性能工作 | -| P11 转出(性能):设备上 MC 26.3,split T2 相对单进程采纳的 p99 Espryt +37–42%、Magma 约 2.5×;其中一部分是线程落位——server apply 线程钉在 6–7 核,client GL 线程多半落到慢核,每帧 CPU 约 2.3×(见 git 历史)。RSS 一半已由 B2(T0)交付:峰值内存 Espryt −41–42%、Magma −18–26%(ID-P11-17) | 路线图推完后的性能工作(p99 与线程落位) | -| P11 转出(B2,性能):`glBufferStorage(NULL)` 的采纳先把整块零存储当 `resource_subdata` 发一遍(T2 与 T0 都是;MC 26.3 8 个存储、441.5 MiB) | 路线图推完后的性能工作 | -| P12 未做:DirectGLES `g_Display` / `g_Surface` / `g_Context` 仍是全局(每进程一个会话时不需要);cached-app freezer 的完整处理(文档从未定义);多 context;server 窗口不转发输入 | 等出现第二个会话 / 第二个 context 的需求 | -| P9 转出:Magma 每次 draw 对可写 SSBO / texel buffer / XFB 目标发整 buffer 的 `OnGpuWritten`(create-indirect 首帧 7,093 条),client 已自标同一批,冗余无害;`OnMipLevelsGenerated`、`OnCapsInvalidated` 仍无生产者。`OnTextureWriteback` 也无生产者,但别删:CPU 三通道 mip 退路要它(`CONTRACT-P5B.md:255`) | 以后的收窄 / 清理候选(ID-P9-7) | -| 树外脚本:普查跑器、`wsl_p5_gate.sh` 等在 `~/w7/notes/`,git merge 不会传播;事实上的门脚本见 git 历史 | 需要时入库 | +| CI coverage: `test.yml` / `apk.yml` switch `MOBILEGL_CI_DISAGGREGATED` and lanes by branch name (`feat/disaggregated`, `codex/fix-github-ci`); this check covers 14 places in `test.yml` and 4 in `apk.yml`; the pull build has only G1 and the monolith comparison, no integration test gate (`TextureRemintPullScenario` was red on pull from P9 until P11 M before it was fixed); after merging into `dev`, the inproc acceptance and the two APK split arms are turned off by branch name, while build-linux-split / integration-split / retrace-split are unconditional | Needs a ruling: whether to add a pull integration lane before merging; the trigger conditions of each lane after merging into `dev` (and delete the `feat/disaggregated` trigger while at it) | +| P9 handoff: `TCP_USER_TIMEOUT` = 5000 ms — the kernel disconnects when the client stops reading control for more than 5 s and there are pending log bytes to send; the blocking write in `PublishSessionFault` waits at most the same 5 s for a client that stopped reading (ID-P9-10). Risk scenario: FCL backgrounded and paused + cross-machine TCP | Needs a ruling: recommend raising it to tens of seconds and making `PublishSessionFault` a bounded write; the user sets the value | +| P11 handoff (B0 F1): HyperOS freezes the entire uid of the server app when the screen goes off. B1 is already solved by a user setting (both the server app and the app hosting the client set battery to "unrestricted", ID-P11-16); what remains is keep-alive for the same-machine FCL use case | Needs a ruling: document it only / detect the power-saving policy in the app and guide the user / do nothing | +| P11 handoff (B2): T0 was measured only on one Redmi with an Adreno; Mali and others have only shell-domain evidence from spike B (the server self-test falls back to T2 on unsupported devices). The mutation "release the import immediately on respecify" does not turn red on Espryt (the driver probably holds its own reference, unverified); release with a fence is kept | Needs a ruling (limited by device rules): bring up a Mali and retest, or accept the self-test fallback long term | +| P11 handoff (B1): the apply-thread policy for external clients was measured only on one Redmi (two big cores); Magma openra stalls at the server on both data planes (~285 fps), and shared memory brings no gain | Same as the row above | +| P12 not done: TLS (open question 21 at the time said "the token is enough; TLS is kept as a P12 open item"; P12 has closed) | Needs a ruling: formally drop it, or keep it as an open item | +| `MOBILEGL_IPC_IDLE_EXIT_S` unresolved (the server already exits immediately on client EOF) | Needs a ruling: recommend retiring it; after approval delete `design/09-build-switches-counters.md:67` and the `Config.h` comments and so on | +| P10 handoff: `GL_ARB_gpu_shader_fp64` is advertised according to the server's `MOBILEGL_ADVERTISE_FP64`, but fp64 narrowing is in the client's compilation; under tcp, when the server's environment differs the two disagree (the similar `GL_KHR_parallel_shader_compile` is already fixed; the approach is in `CapsMirror.cpp:72-101`, ID-P10-10) | Can proceed (small fix) | +| P11 handoff: when client and server share a log prefix, the client opens `.server.log` with `"w"` to write forwarded server logs (`MobileGL/MG_Util/Debug/Log.cpp:89`), truncating the server's own file; two processes on the same machine with the same prefix truncate each other the same way | Can proceed (small fix) | +| P11 handoff (B1): when the session slot is held by a slow-starting program, a second client that sends Hello within 2 s gets a named `Refuse{Busy}`, and a slower one only sees the send fail (that path does not read the pending refusal); already written into the contract | Can proceed (small fix) | +| P11 handoff (B1): after a session start failure the client also reports a misleading extra `Fatal{CapsBeforeFirstSnapshot}` (`CapsMirror.cpp:247`, predates B1; every rejected helper user sees it) | Can proceed (small fix) | +| P11 handoff (B2): the handle arm's CPU reader lands queued resident writes before reading the adoption / T0 mapping — the split half is already implemented by P8-C (`SplitHostBytesForCpuRead`'s T0 arm: land the write + `glFinish`, ID-P8-9), but the host has no T0 and could not prove red | Needs device verification (Redmi Android integration test + static-peek) | +| P11 handoff (B2): when the server grants T0 but the client chose T2, every storage's `map_persistent` waits 2 s and then is refused by name (in production grant and caps agree; seen only under mutation) | Can proceed (small fix: one "client does not want T0" hint per session) | +| P9 handoff: on the Espryt re-mint retain path, `imageLoad` occasionally reads an old value after a framebuffer clear (host 3/30, 0/30 after adding a barrier; `TextureRemintPullScenario` case C pins the barrier for now), suspected llvmpipe (ID-P9-11); seen once on the push monolith arm after P11 merged dev, and `ImageBindableRemintScenario` also pins the barrier (ID-P11-6) | Can proceed (attribute on Redmi without the barrier) | +| P8 handoff (D): when the application omits `glMemoryBarrier`, neither arm has a dependency between compute writes and vertex shader reads (undefined by GL, but real applications rely on it); the per-round barrier cost of D on device is unmeasured; create-indirect (now the derived `minecraft-1.21.1-neoforge-create-indirect-in-world-align1024`, same content) cannot verify these two things (ID-P8-14); a fixture is needed for "a compute write command, no application barrier, no rewrite" | Pending attribution (needs a new fixture) | +| P8 handoff (E): the driver-written mark is applied to the whole texture (`GenerateMipmap` also marks it); when the driver refuses reads, even the base level is refused by name, which is conservative; cross-format copy stores are not followed; a refusal is still a session Fatal (the reply state would have to change to answer `GL_INVALID_OPERATION`) | Small fix (mark per level); the rest as needed | +| P8 handoff (B): `PipeCalls.def:260` `GenerateMipmap` is still `kWaitApplied`; the reason for ruling 14 (CPU filtering touches the client shadow) no longer holds, so it can become `kWaitNone` | Performance work (protocol behavior change, needs a separate ruling) | +| P8 handoff (C): server SSBO marking is over-approximate (every SSBO bound in the window is marked); a buffer that stays bound to an SSBO and is also used as a restart EBO is read back on every draw | Performance work | +| P13 handoff (ID-P13-2, P14 update): Magma monolith record arm vs dev (pull) — traces are now largely caught up: rd12 83.8 vs 87.0 fps (−4%), openra 747 vs 293 (dev waits on the GPU there); P14's largest item is `553eb86d` (texture-layer uploads no longer wait on the CPU for the GPU to drain, rd12 70→83). But **still behind on FCL MC**: monolith 171 vs dev 232 (−26%), inproc 195; the presentation thread's CPU is only about 2.8 / 5.8 ms of the frame, the rest is waiting — another wait different from the traces | First item of the next phase: off-CPU profile of FCL Magma monolith (`--trace-offcpu`, the same method that found the upload wait; neither capture at P14 close caught a game frame), find that 3 ms wait; numbers in git history | +| ~~P13 handoff (W9): cache capacity re-tuning~~ **P14 closed (readout)**: `MOBILEGL_PIPE_STATS` on rd12 / openra shows render-state CSO steady state mints 0 new per frame, Magma pipeline memo hit rate 99.0% / 92.7%, no cache thrash, P8 capacity kept | Closed (W9 section, see git history) | +| P14 handoff: Espryt monolith record arm vs dev (pull) rd12 91.1 vs 115.2 fps (−21%); FCL MC 198 vs 229 (−13%). Render thread CPU per frame 11.56 vs 9.07 ms: client half +1.39 (validate 0.92: EmitGlobalConstants 0.17, EmitVertexElements 0.13, Tracker::Update 0.12, CopyField 0.10, validate itself 0.10, EmitVertexBuffers 0.07; verb port about 0.2), backend +0.45 (SyncNeccessaryTextures +0.14, SyncNeccessaryBuffers +0.08, AdoptUnchangedBufferSets +0.09, BindCurrentProgramWithResources +0.07, SyncCurrentProgramByHandle +0.05), driver +0.33, applier +0.07. Each item is below 2% of frame time; together they are the record arm's structural cost: pull's backend reads frontend objects by pointer at draw time, while push must detect change (tracker), serialize (emitter, uniform span), apply (applier), and then the backend resolves again by handle through the slot table, and because the backend cannot see frontend dirty bits it does a clean check for every bound object — tens of ns per step per draw, each a separate cold cache line, multiplied by 1471 draws/frame | Next phase: per-(VAO, program) draw-packet cache (design draft (see git history), estimated to recover 1.0–1.6 ms/frame for rd12 Espryt monolith, about 91→100–106 fps); first prototype and measure only the client half | +| P14 handoff: Espryt monolith's driver item +0.33 ms/frame (2.9%), all inside `glDrawElements`, with the GL call combination the same as dev. `simpleperf stat` (whole run, render thread): feat executes 16.6% more instructions than dev, L1D refill 56% more, L2D 23% more (IPC 3.73 vs 3.86). Inference: the record arm's larger per-draw working set (record, applier state, slot table, twin) pushes the driver's state out of cache — this is a counter inference, not measured inside the driver | Verify together with the draw-packet cache: measure L1D refill and driver ms/frame before and after landing; if the driver item does not drop, the inference does not hold, and investigate separately | +| P14 handoff (tested, not done): frontend change-epoch fast path for Tracker / residual — bump a context epoch at every `DECLARE_GL_FUNCTION_END` entry (except draw, `glBindVertexArray`, floating-point `glUniform*`), as well as handwritten entries and EGL entries; when the epoch has not moved, validate only recomputes the VAO / program-derived shutter (cap about 0.07 ms), then, after auditing which residual fields depend on VAO / program binding, skips the residual copy (0.15–0.25 ms total, 1.5–2%) | Each is below the 2% threshold, and missing the bump at one entry renders stale state; merge into the draw-packet design (its §3 context epoch is exactly this), do not do it separately | +| P13 handoff (FCL soak, user ruling: FCL is not changed for now, and MobileGL does not work around it): FCL game process can die silently (exit SIGNALED status=34, SIGRTMIN+2): the JVM signal reset after renderer selection drops libcore's AsynchronousCloseMonitor handler, and FCL's okhttp/Okio watchdog then kills the process; renderer-independent (reproduced on P12 and P13 libraries, both backends; untested with other renderers). Soak: P13 library 30 runs (Magma 22 / Espryt 8) died 18 times, P12 library 10 runs died 2; a P12 / P13 alternating control run by run (same scenario, same network period) P12 4/10, P13 2/10, the timeline (`Renderer:` line to MobileGL's first line about 6.2 s, the late death fixed about 9.4 s after it) identical for both libraries, with no evidence that MobileGL raises the probability; all status=34, no tombstone, no kgsl; evidence and mechanism in git history | fix belongs in FCL (save/restore libcore's SIGRTMIN+2 sigaction around JVM creation); left for the user | +| P8 handoff (MD): dev's `RingAllocateSlow` drains without limit on a context in the error state (hangs in `glFinish` on device) | Small fix (dev) | +| P8 handoff: `LogForwardChannel.APeerThatStopsReadingCostsWarnLinesNotTheCallersTime` times out under load (twice), always passes when run alone | Small fix (relax the deadline or isolate) | +| P8 handoff (SV): `gen_pipe_dirty_surface.py` scans integration test sources; a test member with the same name as a GLContext member (e.g. `m_parameters`) silently breaks its self-check; `.Mip3DValidation.` is a failure rather than a skip on lanes without the validation layer | Small fix / CI record | +| P8 handoff (MF): near the two flush ladders, a few comments still name the old freeze / pin commits (`5cb826b0`, `3e298c9a`) | Documentation small fix | +| P8-0 handoff: SSIM < 0.99 already present in the device baseline — 1.21.11-main-menu (Espryt 0.890, Magma 0.165), derivative-main (Espryt 0.851); present on both arms | Pending attribution | +| P12 not done: D8 window-kind whitelist — X11 / MetalLayer / Win32Hwnd / None are still accepted (`SurfaceOpCodec.cpp:138-141`), `HandleFromToken` casts the token to a pointer (`ServerLoop.cpp:1228`, via `UnpackWindowHandle`; whether downstream hands it to EGL was not traced to the end) | Can proceed (Ph-class small fix) | +| P12 not done: the fixed landscape server window was not retested | Can proceed (Redmi read-only check) | +| P11 handoff (M2, to dev): dev's `DirectVulkan.SplitRecording.` lane has no `RESOURCE_LOCK`, and its cases read a literal log path — under `-j` they may truncate each other; the copy on the P11 line is already fixed (the duplicate fix for Magma's empty uniform was synthesized into one entry in ID-P8-17) | Bring it along on the next back-merge to dev | +| P11 handoff (M2): large layers beyond the stage chunk budget are sent as shards, and shards not covered by a write box still carry the whole box (the server needs it to assemble the layer image), which paints the shadow over places the GPU wrote; the fix needs a "locate-only" region form that both servers skip, control protocol revision +1 (split-only, predates P11) | Small package or P8 | +| P11 handoff (M2): uploads still have two lossy shapes, each logged once — when a layer's precise write boxes exceed 4096, it is sent covered by the storage's rectangle table; when an applier entry accumulates more than 4096 regions, they are merged into a union box. When the texture has GPU writes, both paint the shadow into the gaps | Small fix, no trigger reported | +| P10 handoff (performance): on device, of the 19.4 ms per frame of tcp loopback rd12, ~11.2 ms is the producer parking in the stream transport (send + ring / stage / ack waits), credit waiting only ~0.2 ms (see git history §2, ID-P10-13) | Performance work after the roadmap completes | +| P11 handoff (performance): on device with MC 26.3, split T2 relative to monolith adoption p99 Espryt +37–42%, Magma about 2.5×; part of that is thread placement — the server apply thread pinned to cores 6–7, the client GL thread mostly lands on slow cores, about 2.3× CPU per frame (see git history). Half of RSS is already delivered by B2 (T0): peak memory Espryt −41–42%, Magma −18–26% (ID-P11-17) | Performance work after the roadmap completes (p99 and thread placement) | +| P11 handoff (B2, performance): adoption of `glBufferStorage(NULL)` first sends the entire zeroed storage once as `resource_subdata` (both T2 and T0; MC 26.3 8 storages, 441.5 MiB) | Performance work after the roadmap completes | +| P12 not done: DirectGLES `g_Display` / `g_Surface` / `g_Context` are still globals (not needed when there is one session per process); full handling of the cached-app freezer (the docs never defined it); multiple contexts; the server window does not forward input | Wait for the need for a second session / second context | +| P9 handoff: Magma sends a whole-buffer `OnGpuWritten` for writable SSBOs / texel buffers / XFB targets on every draw (7,093 on create-indirect's first frame); the client already marks the same set itself, redundant and harmless; `OnMipLevelsGenerated` and `OnCapsInvalidated` still have no producer. `OnTextureWriteback` also has no producer, but do not delete it: the CPU three-channel mip fallback needs it (`CONTRACT-P5B.md:255`) | Future narrowing / cleanup candidates (ID-P9-7) | +| Out-of-tree scripts: the census runner, `wsl_p5_gate.sh`, and so on are in `~/w7/notes/`; a git merge does not propagate them; the de facto gate scripts are in git history | Put them in the repository when needed | -已关闭的历史债(P5 的 27 个 wrong-answer、`rsp` 残余读、P5b 的 inproc 依赖、ABI 指纹、默认 staging 装不下 128 MiB 上传、184 符号棘轮 CI 门)及当时的完整债务表见 git 历史。 +Closed historical debts (P5's 27 wrong answers, `rsp` residual reads, P5b's inproc dependency, the ABI fingerprint, the default staging being unable to hold a 128 MiB upload, the 184-symbol ratchet CI gate) and the full debt table of that time are in git history. diff --git a/docs/Disaggregated/MEASUREMENTS.md b/docs/Disaggregated/MEASUREMENTS.md index dd613303..7f52377d 100644 --- a/docs/Disaggregated/MEASUREMENTS.md +++ b/docs/Disaggregated/MEASUREMENTS.md @@ -1,53 +1,53 @@ -# 实测(索引) +# Measured results (index) -> 这一页只有结论和去向;完整的表、命令、协议与读法在各阶段的"实测"节(原文见 git 历史)。代码和旧笔记里的 `MEASUREMENTS.md §N` 按下表"§"列找到对应阶段(小节编号在那里原样保留)。 +> This page holds only conclusions and pointers; the full tables, commands, protocols, and how to read them are in each phase's "measured results" section (originals in git history). `MEASUREMENTS.md §N` in code and old notes maps to the phase in the "§" column below (subsection numbering is preserved there as-is). -**口径**:性能只记录、不设门;看**逐线程 CPU 时间**,不看整机帧率。性能对比只用一台手机(Redmi `2f7cbe2e`,Adreno 830),定频、同热窗口、两臂交替跑([`guide/pin-verification-2026-09-07.md`](guide/pin-verification-2026-09-07.md))。 +**Basis**: performance is recorded only, never gated; look at **per-thread CPU time**, not whole-machine frame rate. Performance comparisons use only one phone (Redmi `2f7cbe2e`, Adreno 830), with pinned clocks, the same thermal window, and the two arms run alternately ([`guide/pin-verification-2026-09-07.md`](guide/pin-verification-2026-09-07.md)). -## 关键结论 +## Key conclusions -- **接口本身的代价**:单进程里改成"前端推、后端收",CPU 多约 6–12%(P2),已接受;顶点数组切换密集的场景更高(P3a,+27–30%)。 -- **拆成两线程**:起初游戏里只有 7–13 fps;优化后 103–106 fps(P5d);client 发完就走以后,重负载(渲染距离 32)下与单线程持平(P5e)。 -- **拆成两进程**:真机上与两线程成本持平;两者的 GL 线程 CPU 都比单线程少约 30%(后端工作挪到了另一线程 / 进程)(P6)。 -- **跨机**:电脑经 TCP 连手机,102 个集成用例全过;server 被杀后 133 ms、Wi-Fi 断开后约 5 s 干净报"设备丢失"(P6.5)。 -- **纹理上传的等待粒度(P12,handoff §4)**:wire 臂上纹理那半 `resource_subdata` 不再逐条买回包,等待点从「每条记录」落到「SEG_STAGE 窗口用尽」。 - 单条纯上传占用的回包等待 **1 → 0**(`wait_replies`,正是 §3.2 里"一帧 55,428"的那个计数器)。 - 按形状实测(`RemoteClientControls.ReplyWaitsByOpForAnAtlasShapedLoad`,主机 inproc,按 op 计数):**图集拼接**(一张 level 上 64 次 `glTexSubImage2D`)**64 → 0** 次回包等待; - **每 sprite 一张纹理**(64 张纹理 + 256 次 `glTexParameteri`)**384 → 320**,剩下的全是 per-resource / per-call 的三条 row(create 76 / respecify 130 / params 130)—— - **这两条后来被"首次使用确认"取代了**(见下面那条):对象的存在性由它自己的 create 确认为事实之后, - params 与 texture respecify 都不再逐条买答案,而是只在**首次使用**时付一次阻塞的 create。 - 同一帧的累计实测:**43,232 waits / 221.5 s → 4,543 waits / 31.3 s(7.1×)**,staged 字节与发出的记录数(103,094)都不变。 - 真机(TrebleDroid GSI,MC 26.2 经 TCP 入世界)那一帧的构成为 `ResourceRespecify` 20,633 + `SetTextureParams` 18,056 + `ResourceCreate` 4,536 条**各等一次**, - 而 `ResourceSubData` 12,671 条**零等待**(B 的实机证据);这些记录都是真实状态变化,客户端没有可去重的(同一值的 `glTexParameteri` 本来就不产生记录)。 -- **单次往返那 ~5 ms 是设备侧的深度空闲退出,不是链路也不是客户端**(P12,本轮实测):同一帧、同一批记录, - 客户端自旋 40× 只快 ~10%;换 `adb forward`(USB)快 ~25–30%;而把设备 8 核钉 `performance` 并关掉 `cpuoff_l`/`clusteroff_l`/`mcusysoff`/`s2idle` 后, - 单次等待 **5,040 → 3,715 µs**、那一帧墙钟 **221.5 s → 166.5 s(−25%)**——记录数与字节数都不变。 - 这解释了 handoff §3.6「换快 3.4 倍的链路墙钟不变」:钱花在设备每次唤醒上;handoff §3.2 那 249 s 是在**未定频**的机器上取的,含这份空闲税。 - **同一个诊断给出一条可移植修法**:把服务端的自旋预算调大(Activity 的 `env` extra → `MOBILEGL_IPC_SPIN_US=2000`,不需要 root、不需要改代码), - 那一帧 **221.5 s → 182.8 s(−17%)**;设备定频+关深度空闲则是 **166.5 s(−25%)**。服务端日志会打印 `spin 2000 us` 自证。 - 见 git 历史 §2.6–2.10。 -- **画面正确**:Vulkan 后端真机画面检查 36/36 通过,CTS 五块相对基线没有超过 0.5 个百分点的退步、没有新崩溃(P7);server 自有窗口上屏两后端 SSIM 1.0(P12)。 -- **五臂传输对比(2026-09-28,未定频交错 A/B)**:重负载(rd12)下 inproc ≈ spawn+shm 比 monolith **快约 1/3**(run-ahead 流水线并行 + applier 路径探针更少),轻负载(openra)下 split 只付固定开销;**tcp localhost 慢 ~8 倍,瓶颈是 present credit=1 的串行等待(~74%)+ futex 唤醒税**,`MOBILEGL_IPC_SPIN_US=2000` 单项实测 21.7→63.6 fps;跨主机 TCP 的「`eglMakeCurrent` hang」**是测试环境造成的**(主机 v2rayN `xray_tun` 代理终结 TCP 后中继卡住,不是源码 bug);绕开后 P12 出口门 (b) 通过:WSL client 经 Wi-Fi 重放 rd12 世界内 trace,ssim 0.999883,稳态 17–22 fps(`PRESENT_CREDIT` 1/2/3 = 16.9 / 21.3 / 22.1),openra 稳态 105–133 fps;加载帧 2.7 GB 受带宽约束(server 实测 52 MB/s),稳态受往返延迟(20–24 MB/s)。全文见 git 历史。 +- **Cost of the interface itself**: in the monolith, changing to "frontend pushes, backend receives" costs about 6–12% more CPU (P2), which was accepted; scenes with dense vertex-array switching are higher (P3a, +27–30%). +- **Split into two threads**: at first only 7–13 fps in the game; after optimization 103–106 fps (P5d); after the client runs ahead, under heavy load (render distance 32) it matches single-threaded (P5e). +- **Split into two processes**: on device the cost matches two-thread; the GL thread CPU of both is about 30% lower than single-threaded (backend work moved to the other thread / process) (P6). +- **Cross-machine**: a PC connects to the phone over TCP, all 102 integration cases pass; after the server is killed, 133 ms; after Wi-Fi disconnects, about 5 s to cleanly report "device lost" (P6.5). +- **Texture upload wait granularity (P12, handoff §4)**: on the wire arm, the texture half of `resource_subdata` no longer buys a reply per record; the wait point moves from "every record" to "SEG_STAGE window exhausted". + A single pure upload occupies a reply wait of **1 → 0** (`wait_replies`, exactly the counter that was "55,428 per frame" in §3.2). + Measured by shape (`RemoteClientControls.ReplyWaitsByOpForAnAtlasShapedLoad`, host inproc, counted per op): **atlas assembly** (64 `glTexSubImage2D` calls on one level) **64 → 0** reply waits; + **one texture per sprite** (64 textures + 256 `glTexParameteri` calls) **384 → 320**, and the rest is entirely the three per-resource / per-call rows (create 76 / respecify 130 / params 130) — + **these two were later replaced by "first-use confirmation"** (see the item below): once an object's existence is confirmed as fact by its own create, + params and texture respecify no longer buy an answer per row; instead a blocking create is paid once at **first use**. + Cumulative measured result for the same frame: **43,232 waits / 221.5 s → 4,543 waits / 31.3 s (7.1×)**, with staged bytes and the number of records sent (103,094) both unchanged. + On device (TrebleDroid GSI, MC 26.2 entering the world over TCP), that frame consisted of `ResourceRespecify` 20,633 + `SetTextureParams` 18,056 + `ResourceCreate` 4,536 records **each waiting once**, + while `ResourceSubData` 12,671 records **waited zero times** (B's on-device evidence); these records are all real state changes, and the client had nothing to deduplicate (a `glTexParameteri` with the same value produces no record in the first place). +- **The ~5 ms per round trip is the device-side deep idle exit, not the link and not the client** (P12, this round's measured result): same frame, same set of records, + the client spinning 40× was only ~10% faster; switching to `adb forward` (USB) was ~25–30% faster; and after pinning the device's 8 cores to `performance` and turning off `cpuoff_l`/`clusteroff_l`/`mcusysoff`/`s2idle`, + a single wait went **5,040 → 3,715 µs** and that frame's wall time **221.5 s → 166.5 s (−25%)** — with record count and byte count unchanged. + This explains handoff §3.6 "switching to a link 3.4× faster leaves wall time unchanged": the money is spent on each wake-up of the device; the 249 s in handoff §3.2 was taken on a machine **without pinned clocks** and includes this idle tax. + **The same diagnosis yields a portable fix**: raise the server's spin budget (the Activity's `env` extra → `MOBILEGL_IPC_SPIN_US=2000`, no root and no code change needed), + and that frame goes **221.5 s → 182.8 s (−17%)**; pinning device clocks + turning off deep idle gives **166.5 s (−25%)**. The server log prints `spin 2000 us` as proof. + See git history §2.6–2.10. +- **Frames are correct**: the Vulkan backend's on-device frame check passes 36/36; the five CTS blocks show no regression beyond 0.5 percentage points against baseline and no new crashes (P7); on-screen presentation in the server's own window gives SSIM 1.0 on both backends (P12). +- **Five-arm transport comparison (2026-09-28, unpinned-clock interleaved A/B)**: under heavy load (rd12) inproc ≈ spawn+shm is **about 1/3 faster** than monolith (run-ahead pipeline parallelism + fewer applier-path probes); under light load (openra) split pays only fixed overhead; **tcp localhost is ~8× slower, the bottleneck being present credit=1 serial waiting (~74%) + futex wake-up tax**, `MOBILEGL_IPC_SPIN_US=2000` alone measured 21.7→63.6 fps; the cross-host TCP "`eglMakeCurrent` hang" **was caused by the test environment** (the host's v2rayN `xray_tun` proxy terminated TCP and the relay hung, not a source bug); after bypassing it P12 exit gate (b) passes: the WSL client replays an in-world rd12 trace over Wi-Fi, ssim 0.999883, steady state 17–22 fps (`PRESENT_CREDIT` 1/2/3 = 16.9 / 21.3 / 22.1), openra steady state 105–133 fps; the 2.7 GB loading frame is bandwidth-bound (server measured 52 MB/s), steady state is round-trip-latency-bound (20–24 MB/s). Full text in git history. -## 按阶段 +## By phase -| § | 阶段 | 一句结论 | 全文 | +| § | Phase | One-line conclusion | Full text | |---|---|---|---| -| 1 | P0 | 能从应用进程拉起第二个进程;跨进程共享 GPU 内存只有一条路在所有设备上可用 | git 历史 | -| 2 | P1 | 逐 draw 核对推送状态,79 条 trace 零分歧 | git 历史 | -| 3 | P2 | 桌面基准:新 tracker 比它替掉的旧填充更便宜 | git 历史 | -| 4 | P3a | 两机真机 Release:接口代价 +6–12%,VAO 切换密集的场景 +27–30% | git 历史 | -| 5 | P4a | 换到 Redmi;P4a 自己只加 3–6 个百分点 | git 历史 | -| 6 | P5 | 两线程第一帧画对;真机两线程臂还跑不完 | git 历史 | -| 7 | P5b | 真机两线程跑通四条游戏 trace;两线程额外代价 +6–18% | git 历史 | -| 8 | P5c | 两线程之间零共享内存后,全部测试仍绿 | git 历史 | -| 9 | P5d | 游戏内 7–13 → 103–106 fps,client CPU 15.0 → 9.2 ms/帧 | git 历史 | -| 10–11 | P5e | 发完就走比每条都等快 69%;重负载下与单线程持平 | git 历史 | -| 12 | P6 | 两进程与两线程持平;每帧数据量与记录数首次实测 | git 历史 | -| 13 | P3b/P4b | 纹理上传形状在四种拓扑下完全一致 | git 历史 | -| 14 | P6.5 | 跨机 TCP 102/102;断线约 5 s 检测到 | git 历史 | -| 15 | P7 | 真机画面 36/36;server 内存无界增长收住(主机 825 → 546 MiB) | git 历史 | -| 16 | P12 | 审查后真机复测:Espryt SSIM 1.0;Magma 1.0 / 0.999999511;P12 定向 CTest 46/46;纹理上传回包等待 1→0(主机机制门,真机墙钟待测);**P12 已收官(09-29)**:跨机 TCP 门 (b) 通过(rd12 ssim 0.999883、稳态 17–22 fps);FCL 门 (a) 通过(Minecraft 上屏到 render server 窗口,杀 server 后 33–54 ms 闩住 device-lost) | git 历史 | -| 17 | 五臂传输测量(2026-09-28,非阶段) | inproc/shm 重负载比 monolith 快 ~1/3;tcp localhost 瓶颈是 credit=1 + 唤醒税(SPIN_US=2000 → 2.9×);跨主机 hang 实为主机 xray TUN 代理造成;直连 Wi-Fi 稳态 rd12 17–22 fps、openra 105–133 fps | git 历史 | -| 18 | P11 | 同机零拷贝(T0)MC 26.3 峰值内存 Espryt −41–42%、Magma −18–26%,ssim / 帧时 / CPU 不变;外部 client 走共享内存 rd12 Espryt 约 119 fps(TCP 40–53);split T2 相对单进程采纳 p99 Espryt +37–42%、Magma 约 2.5×。未量:M2 后 split server 上纹理无 GPU 写时 Espryt 自己按存储阈值取舍精确写入框,非 ring 路径可能多发几个小框 | git 历史 | -| 19 | P8 | 真实内容只 Magma wire indirect 命中(MC 26.3 × Magma inproc 1,300 万 draw CPU 展开)→ 原生后 create-indirect 每次整 GPU 等待 321 → 0;红米 create-instancing × Espryt × monolith 0.870 → 0.99998(Adreno 丢排队环形拷贝,dev + feat 两条阶梯);最大 program archive 355 KB = arena/4 的 4.2 %(不分片);出口设备矩阵 77 格 / 臂无一变差 | git 历史 | +| 1 | P0 | A second process can be launched from the application process; cross-process GPU memory sharing has only one path available on all devices | git history | +| 2 | P1 | Verify pushed state per draw; 79 traces with zero divergence | git history | +| 3 | P2 | Desktop benchmark: the new tracker is cheaper than the old fill it replaced | git history | +| 4 | P3a | Two devices, on-device Release: interface cost +6–12%, scenes with dense VAO switching +27–30% | git history | +| 5 | P4a | Switched to Redmi; P4a itself adds only 3–6 percentage points | git history | +| 6 | P5 | The first frame draws correctly in two threads; the on-device two-thread arm still cannot run to completion | git history | +| 7 | P5b | Four game traces run to completion in two threads on device; two-thread extra cost +6–18% | git history | +| 8 | P5c | With zero shared memory between the two threads, all tests still green | git history | +| 9 | P5d | In-game 7–13 → 103–106 fps, client CPU 15.0 → 9.2 ms/frame | git history | +| 10–11 | P5e | Running ahead is 69% faster than waiting on every command; matches single-threaded under heavy load | git history | +| 12 | P6 | Two-process matches two-thread; first measured data volume and record count per frame | git history | +| 13 | P3b/P4b | Texture upload shapes are identical under all four topologies | git history | +| 14 | P6.5 | Cross-machine TCP 102/102; disconnect detected in about 5 s | git history | +| 15 | P7 | On-device frames 36/36; unbounded server memory growth reined in (host 825 → 546 MiB) | git history | +| 16 | P12 | On-device retest after review: Espryt SSIM 1.0; Magma 1.0 / 0.999999511; P12 targeted CTest 46/46; texture upload reply waits 1→0 (host mechanism gate, on-device wall time pending); **P12 closed (09-29)**: cross-machine TCP gate (b) passes (rd12 ssim 0.999883, steady state 17–22 fps); FCL gate (a) passes (Minecraft presented on screen in the render server window; after killing the server, device-lost latches in 33–54 ms) | git history | +| 17 | Five-arm transport measurement (2026-09-28, not a phase) | inproc/shm under heavy load is ~1/3 faster than monolith; tcp localhost bottleneck is credit=1 + wake-up tax (SPIN_US=2000 → 2.9×); the cross-host hang was actually caused by the host's xray TUN proxy; direct Wi-Fi steady state rd12 17–22 fps, openra 105–133 fps | git history | +| 18 | P11 | Same-machine zero-copy (T0) MC 26.3 peak memory Espryt −41–42%, Magma −18–26%, ssim / frame time / CPU unchanged; external client over shared memory rd12 Espryt about 119 fps (TCP 40–53); split T2 relative to monolith adoption p99 Espryt +37–42%, Magma about 2.5×. Not measured: after M2, on the split server, when a texture has no GPU writes, Espryt chooses the precise write box by its own storage threshold; the non-ring path may send a few extra small boxes | git history | +| 19 | P8 | On real content only Magma wire indirect hit (MC 26.3 × Magma inproc 13 million draws expanded on CPU) → after going native, the per-create-indirect full-GPU wait 321 → 0; Redmi create-instancing × Espryt × monolith 0.870 → 0.99998 (Adreno drops queued ring copies, the dev + feat two ladders); largest program archive 355 KB = 4.2% of arena/4 (no chunking); exit device matrix 77 cells / arms, none worse | git history | diff --git a/docs/Disaggregated/OPEN-QUESTIONS.md b/docs/Disaggregated/OPEN-QUESTIONS.md index c3eb6465..ba3ad607 100644 --- a/docs/Disaggregated/OPEN-QUESTIONS.md +++ b/docs/Disaggregated/OPEN-QUESTIONS.md @@ -1,30 +1,30 @@ -# 开放问题全文(原 `ROADMAP.md`「开放问题」,2026-09-24 移入) +# Open questions, full text (formerly the "Open questions" section of `ROADMAP.md`, moved here 2026-09-24) -> [`ROADMAP.md`](ROADMAP.md) 只留每题一行的状态;这里是每一题的完整陈述、已答部分的出处与未答部分的判据。编号稳定,引用写 "开放问题 N"。 +> [`ROADMAP.md`](ROADMAP.md) keeps only a one-line status per question; here is the full statement of each question, the source for the answered parts, and the criteria for the unanswered parts. Numbering is stable; cite as "open question N". -P0 已回答的不再列出(spike A 的域、spike B 的分档、`posix_spawn` 不可用、OOM 探测惯用法、`GetInteger64i_v`/`GetProgramiv` 退役、D21 与 `RenderbufferObject` lifetime id、动态 accessor 基线)。 +Questions answered in P0 are no longer listed (spike A's domain, spike B's tiers, `posix_spawn` unavailable, the OOM probing idiom, retirement of `GetInteger64i_v`/`GetProgramiv`, D21 and the `RenderbufferObject` lifetime id, the dynamic accessor baseline). -1. **client 侧 dirty 走查的真实每 draw CPU 代价。** 已答(P2–P4a):推送没有在拉取基线之下净减少;Release 下 P2 边界 +6–12%,P3a 在 VAO 切换密的 rd12 上再加 +17–19 pt,P4a 在 Espryt 上 +3.4–5.7 pt(`MEASUREMENTS.md` §3–§5)。用户 2026-09-08 接受,性能自此只记录。 -2. **真实语料上纹理重铸拉取的发生率。** 已答(P4a):可忽略,保留 LRU 维持默认 0——79 例 × 两后端 780 个统计窗口里共 2 次(`iris-photon`、`iris-derivative` 各 1,只在 DirectGLES)。但 P5b 下这条路径是具名 Fatal,正是这两条 trace 加 `create-indirect` GLES 的首阻塞(P9)。**P9 W2 关闭**:重铸不需要拉取——server 读 GPU 层、store 补 pending 盒(Espryt),GPU→GPU 拷贝(Magma);77 行 × {monolith, inproc} 普查仍是同两次(都是 store 无字节的渲染目标),`OnTexturePullRequest` 已删(见 git 历史)。 -3. **spike B 的 `untrusted_app` 域复核。** 两台设备的分档在 `shell` 域测得;从应用进程再跑一次 `extmem_probe`(spike A 的 exec 钩子已可用)。P11 前做。**2026-09-22 降级**:只对同机臂的 T0 / T1 有意义,stream 数据面不需要。 -4. **渲染状态的 wire 粒度。** 已答(P2):16 个边界 / 15 个 chunk,7 pipeline 396 B + 8 dynamic 772 B;CSO LRU 64 暂定,P13 重调。 -5. **无存储的 capability。** 已答(P2):`FramebufferSrgb`、`DepthClamp`、`TextureCubeMapSeamless` 三个都补了真存储,`sizeof(RenderStateParameters)` 仍 1168。 -6. **具名 UBO host payload 的形状(D-B8)。** Magma 在 26.3 世界每帧重打包 331 KB 具名 UBO 字节,Espryt 为 0。要么冻结第二变长尾形状,要么走备选(Magma 直接描述符绑定常驻 `VkBuffer` range,独立 `dev` PR)。P7。 -7. **`MG_Util` 的切割缝。** server 需要 SPIRV-Cross / ESSL 转译缓存 / 格式处理器 / POST 探针,client 需要 glslang 与反射层;`MG_Util` 内部是否有干净的 Transpile-vs-Reflect 缝未审计。P7。 -8. **一份反射归档能否服务三个消费者。** Espryt 那一半已答(P4a):能且不需要复制。Magma 的第一个消费者已由 P5f fm 答:`MagmaProgramSource` 全部从 wire `ProgramArchive` 取,无前端对象、无复制。第二个(storage block 表)今天是**否**且变差了:split 下 `MagmaProgramSource::EnsureStorageBlocks` **每 draw** 重跑 SPIRV-Reflect(monolith 臂 `DirectVulkan.cpp:177-200` 至少有持久缓存);答案是往 `LinkArtifacts` 加有序 `storageBlocks`(数据已在 `blockReflection` 里),两个消费者都改读它。**已答(P7 wave 2-C,`dce9953d..cf7ca59f`)**:`storageBlocks` 入归档、两个消费者改读、每 draw SPIRV-Reflect 4→0;`g_programResourceCaches` 的 monolith 半边归 P13(G1)。 -9. **viewport-array 回放能否塞进一次 `draw_vbo`**:**已答(2026-09-30,ID-P8-1)**:能——server 在一次 draw 内按状态分组逐遍回放(`DirectGLES.cpp:8421-8465`),`ViewportArrayScenario` 在 split 各臂绿。 -10. **`ResidentSubData` 的不对称。** 已答一半(2026-09-22 核):**Magma 的实现已补**(`VkBufferManager.cpp:123` monolith 表、`:148` wire 表,`fff9d639f`)。**仍未答:`kCapResidentSubData` 从未被 server 发布**——`MG_Backend/Init.cpp:192-219` 是全树唯一的 `SetCapabilityBits` 生产调用点,只 OR 了 XFB、三个 query 位与 run-ahead 位;于是 `PipeFill.cpp:848` 在 split 下恒 false,**两个后端在拆分模式下都退回 `BufferObject.cpp:711-716` 的就地 memcpy**,Magma 的实现在 split 里是死代码。**已答(P7 wave 2-C,ID-P7-20)**:`InitServerRoleCommon` 按 server 自己的 wire 资源表发布 `kCapResidentSubData`,镜像收到即验收;白盒「发出的是 opcode 49」在 P11 采纳档落地前不可达(§5.4 债)。 -11. **`SEG_STAGE` 的上限。** 内容侧已答(2026-09-20):**分块已实现**——buffer 范围走查(`1e7c372e`)与纹理整宽 slab(`9469d48e`)按 `MGPipeStageChunkBytes()`(默认 32 MiB 的 1/4 = 8 MiB)切成多条 `resource_subdata`,所以单次 128 MiB 上传不再需要显式 `MOBILEGL_IPC_STAGE_MB=256`;单片仍超 arena 或该 record 类型未接入分片时仍是 `Fatal{RingOverrun, "SEG_STAGE"}` 兜底。**仍未答(2026-09-22 收窄)**:a6 §6 实测没走查的只剩 **program archive**(唯一无界 blob)与 **`draw_vbo` 的 `NumDraws*12` range 尾**;宿主索引 span 无 producer(划掉),`set_global_constants` 有走查。二者的分片是 P6.5 sl 与 P8 共用的同一件事,stream 发送窗口对着它们定尺。MC in-world / Create 的占用分布仍未量(门 8 已给出两条负载的字节/帧与记录/帧,逐 blob 分布只在 integration 车道取到)。 **P8-0 实测(2026-09-30,ID-P8-5)**:最大 program archive 354,846 B、最大 `draw_vbo` 记录 1,936 B,都远低于 arena/4;**不做分片,关闭**。 -12. **P13 之后 split-only 渲染 bug 的 server 侧第二意见。** verify 构建 + recorder 只覆盖推送内容,不覆盖后端对它的解释。 -13. **烘焙后的内部 shader 能否在没有活 `ProgramObject` 的情况下表达 uniform location 与 UBO 布局。** 颜色 blit 已答(P5f fv:`WireColorBlit.{vert,frag}` 用 push constant,`WireColorBlitSpirv.h` 签进树);窄化到深度 mip 程序(今天在 split 下被编译掉、其 split 路径是具名 Fatal)与直通 TCS(`ProgramFactory.cpp:4060-4262`,第三个未盘点的内部 shader 生成器)。**已答(P7 wave 2-B / B2)**:深度 mip 烘焙 (A)(D)(`WireDepthMipmap.*`,push constant,`MOBILEGL_BAKED_INTERNAL_SHADERS` 新鲜度门表驱动)与 (B′)(disaggregated 构建的 monolith 臂改用烘焙模块)落地;multisample resolve 第三套烘焙 shader 随 B2;直通 TCS 仍未盘点。 -14. **推送模型改变哪些按拉取模式调过的缓存命中率。** 幸存者容量在 P13 重调。一条线索:设备上 26.3 Espryt 的 `sve` ≈ draw 数(每 draw 重发一次 sampler-view 集合),桌面只有 ~0.07/draw;列入 P3b/P4b 优化清单。 -15. **monolith 的 `*IndirectCount` 不调 `SyncGpuWrites()` 是不是潜在缺口。** 独立 `dev` 问题,拆分不得借机顺手修。**已答(2026-09-30):是**——P8-C / P8-D 主机 red-once 证实(Espryt `*IndirectCount`、Magma `glMultiDrawArraysIndirectCount` 读到 0);split 半已修(ID-P8-9),monolith 半在 P8 第二波的 dev 包里修(ID-P8-3)。 -16. **索引宿主镜像的实际内存占用。** MC / Sodium / Iris 语料里 element-array buffer 总量未测;若显著超 64 MiB,退化路径的频率与代价必须实测。P8。 -17. **`create-indirect` fixture 在 Adreno 830 上的失败**是 `dev@81b17c0b` 就有的(基线 APK 复现),不是本分支造成;`rd12` + Magma 在两台 Adreno 830 上的 `scudo::reportMapError` 崩溃同样是 `dev` 侧。两者排除在设备 A/B 之外、留在桌面语料里;P8 要在 `create-indirect` 上断言 `roundtrips-per-frame == 0`,所以 `dev` 的修复在别人的关键路径上。**create-indirect 部分已答(2026-09-30)**:原 fixture 在 `GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT` = 16 的桌面驱动上抓,Flywheel 按 16 摆 scatter 列表;Adreno 830 两后端与 Mali 的 Vulkan 要 64,1,270 次范围绑定全被 `GL_INVALID_VALUE` 拒掉。原 fixture 退役,换成派生的 `minecraft-1.21.1-neoforge-create-indirect-in-world-align1024`(**不是同一个 trace**:`tools/trace_replay/fixture_tools/realign_buffer_ranges.cpp --align 1024` 把这些绑定挪到 1024 对齐的槽,插入 3,812 个调用,目标调用 504631 → 508443;主机 SSIM 与原 fixture 9 位一致)。红米两后端 monolith / spawn 全过;Mali-G1-Ultra 上 Magma 全过(split 臂另修了 T0 POST,见 `CONTRACT-P11.md` POST 节),Espryt 仍 0.848:该机 GLES 驱动顶点阶段 SSBO 上限为 0,Flywheel indirect 的顶点程序链接不了(能力缺失,不是分离缺陷)。 -18. **split 两侧的负载平衡。** P5e 解锁出来的新问题:VD32(~3550 draws/帧)下 apply 线程 **11-12 ms**、client **15.7 ms**,**client 是瓶颈且打满 ~94%**。把工作从 client 挪到 apply 会直接降瓶颈——这在 lockstep 下毫无意义(两侧串行相加),**run-ahead 才使它成为一个杠杆**。供选:编码侧的 emitter、tracker 走查、持久映射的脏页追踪(`change_protection` 在侧写里占 1.3%)。需先重新侧写:等待消失后尾部各项的分母都变了。排在 P5e 之后;无主,2026-09-22 建议挂在路线图推完后的优化阶段,P6.5 的 2×2 矩阵车道顺带重新侧写 -19. **链路带宽预算与压缩。** TCP 终局下 `SEG_STAGE` 字节/帧对的是 Wi-Fi / USB(量级 30–100 MB/s),不是内存;`ARCHITECTURE.md` §14 的 ~1 MB/帧预算在 60 fps 是 60 MB/s,已贴着 Wi-Fi 上限。是否对 stage 载荷做 LZ4 类压缩、纹理上传是否按内容哈希在 server 侧去重,要等门 8 的分布出来再定。P6.5 契约写下第一行之前必答。 -20. **大单次上传的停顿。** 128 MiB 一次上传在 50 MB/s 上是 2.5 s;内容侧分块解决的是"装不装得下",不是"要等多久"。跨机臂上要么接受并记录,要么给上传做异步化(与 P9 的语义一起想)。不假装解决。 -21. **配对 / 认证的形式。** **已裁定(ID-P7-3,2026-09-22):令牌足够,不做 TLS。** 威胁模型是「任何人都能连的远程代码路径」而不是窃听:令牌常量时间比较、≥16 字节、无令牌只 loopback、数据面以 `Welcome.dataNonce` 绑定到已认证的控制连接、fork 前认证。TLS 作为 P12 的开放项保留。 -22. **client 平台范围。** 默认先 Linux + Android(现有 CI 能验),Windows client 第二批(`ShmSegmentWin32` 在;`pipe:` 具名拒绝作废、TCP 替代),macOS 仍不拆分。这决定 `ARCHITECTURE.md` §15.3 "Windows 机器不是正确性门"要不要改。 -23. **半开连接的检测。** Wi-Fi 掉线不产生挂断事件;dl 的闩取自描述符挂断,TCP 上需要 keepalive / 心跳超时并**由传输层报告为挂断**——这与"绝不取自 apply 超时"不矛盾,写清楚免得重吵。P6.5 ct。 -24. **E1 对照的重定义(ID-122)。** **已关闭(2026-09-29 债务审查)**:`10bfd29f` 把 E1 的像素竞速换成观测协议等待的负控 `scripts/ci/wait_boundary_negative_control.py`。2026-10-18 该负控退役:探针看得见缺失的等待,改由常驻单元用例 `RemoteWaitBoundaryControl.AnUnwaitedPublishIsSeenAsNoWait` 证明(同一个 `ApplierReset`,发布后不等待,必须读到 parked=0)。 +1. **The real per-draw CPU cost of the client-side dirty walk.** Answered (P2–P4a): pushing did not net a reduction below the pull baseline; under Release the P2 boundary is +6–12%, P3a adds another +17–19 pt on rd12 where VAO switching is dense, P4a +3.4–5.7 pt on Espryt (`MEASUREMENTS.md` §3–§5). The user accepted on 2026-09-08, and performance has been recorded only since then. +2. **The incidence of texture re-mint pulls on real corpora.** Answered (P4a): negligible; the LRU is kept and the default stays 0 — 2 times in 780 statistics windows over 79 cases × two backends (`iris-photon` and `iris-derivative` one each, only in DirectGLES). But under P5b this path was a named Fatal, exactly the first block of these two traces plus `create-indirect` GLES (P9). **P9 W2 closed**: re-mint needs no pull — the server reads the GPU level, the store fills the pending box (Espryt), GPU→GPU copy (Magma); the census over 77 rows × {monolith, inproc} is still the same two times (both are render targets whose store has no bytes), and `OnTexturePullRequest` is deleted (see git history). +3. **Re-check of spike B's `untrusted_app` domain.** The tiers for both devices were measured in the `shell` domain; run `extmem_probe` once more from the application process (spike A's exec hook is already available). Do before P11. **2026-09-22 downgraded**: only meaningful for the same-machine arm's T0 / T1; the stream data plane does not need it. +4. **Wire granularity of render state.** Answered (P2): 16 boundaries / 15 chunks, 7 pipeline 396 B + 8 dynamic 772 B; CSO LRU 64 provisional, retuned in P13. +5. **Capabilities without storage.** Answered (P2): `FramebufferSrgb`, `DepthClamp`, `TextureCubeMapSeamless` all gained real storage, and `sizeof(RenderStateParameters)` is still 1168. +6. **The shape of the named UBO host payload (D-B8).** Magma repacks 331 KB of named UBO bytes per frame in the 26.3 world; Espryt 0. Either freeze the second variable-length tail shape, or take the alternative (Magma binds a resident `VkBuffer` range directly at the descriptor, a separate `dev` PR). P7. +7. **The cut seam in `MG_Util`.** The server needs SPIRV-Cross / ESSL translation cache / format handlers / POST probe; the client needs glslang and the reflection layer; whether `MG_Util` has a clean Transpile-vs-Reflect seam inside has not been audited. P7. +8. **Can one reflection archive serve three consumers.** The Espryt half is answered (P4a): yes, and no copy is needed. Magma's first consumer was answered by P5f fm: `MagmaProgramSource` takes everything from the wire `ProgramArchive`, no frontend object, no copy. The second (storage block table) today is **no** and has gotten worse: under split, `MagmaProgramSource::EnsureStorageBlocks` **re-runs SPIRV-Reflect every draw** (the monolith arm's `DirectVulkan.cpp:177-200` at least has a persistent cache); the answer is to add ordered `storageBlocks` to `LinkArtifacts` (the data is already in `blockReflection`), and both consumers read it instead. **Answered (P7 wave 2-C, `dce9953d..cf7ca59f`)**: `storageBlocks` enters the archive, both consumers read it, per-draw SPIRV-Reflect 4→0; the monolith half of `g_programResourceCaches` goes to P13 (G1). +9. **Can viewport-array replay fit into one `draw_vbo`**: **answered (2026-09-30, ID-P8-1)**: yes — the server replays it pass by pass within one draw, grouped by state (`DirectGLES.cpp:8421-8465`), and `ViewportArrayScenario` is green on each split arm. +10. **The `ResidentSubData` asymmetry.** Half answered (checked 2026-09-22): **Magma's implementation is complete** (`VkBufferManager.cpp:123` monolith table, `:148` wire table, `fff9d639f`). **Still unanswered: `kCapResidentSubData` is never published by the server** — `MG_Backend/Init.cpp:192-219` is the only production `SetCapabilityBits` call site in the whole tree, OR-ing only XFB, the three query bits, and the run-ahead bit; so `PipeFill.cpp:848` is always false under split, and **both backends under split fall back to the in-place memcpy at `BufferObject.cpp:711-716`**, making Magma's implementation dead code in split. **Answered (P7 wave 2-C, ID-P7-20)**: `InitServerRoleCommon` publishes `kCapResidentSubData` from the server's own wire resource table, and the mirror accepts it on receipt; the white-box check "what is emitted is opcode 49" is unreachable before the P11 adoption tier lands (§5.4 debt). +11. **The `SEG_STAGE` limit.** Content side answered (2026-09-20): **chunking is implemented** — the buffer range walk (`1e7c372e`) and the texture full-width slab (`9469d48e`) split into multiple `resource_subdata` records per `MGPipeStageChunkBytes()` (default 1/4 of 32 MiB = 8 MiB), so a single 128 MiB upload no longer needs an explicit `MOBILEGL_IPC_STAGE_MB=256`; when a single piece still exceeds the arena or that record type is not wired into chunking, the `Fatal{RingOverrun, "SEG_STAGE"}` fallback remains. **Still unanswered (narrowed 2026-09-22)**: in a6 §6's measured results, the only things not walked are the **program archive** (the only unbounded blob) and the **`draw_vbo` `NumDraws*12` range tail**; the host index span has no producer (struck out); `set_global_constants` has a walk. Chunking both is the same work shared by P6.5 sl and P8, and the stream send window is sized against them. The occupancy distribution of MC in-world / Create is still unmeasured (gate 8 has given bytes/frame and records/frame for the two loads; the per-blob distribution was taken only on the integration lane). **P8-0 measured result (2026-09-30, ID-P8-5)**: largest program archive 354,846 B, largest `draw_vbo` record 1,936 B, both far below arena/4; **no chunking, closed**. +12. **A second opinion on the server side for split-only rendering bugs after P13.** The verify build + recorder cover only what is pushed, not the backend's interpretation of it. +13. **Whether baked internal shaders can express uniform locations and UBO layouts without a live `ProgramObject`.** Color blit answered (P5f fv: `WireColorBlit.{vert,frag}` uses push constants, and `WireColorBlitSpirv.h` is checked into the tree); narrowed to the depth mip program (today compiled out under split, whose split path is a named Fatal) and pass-through TCS (`ProgramFactory.cpp:4060-4262`, the third uninventoried internal shader generator). **Answered (P7 wave 2-B / B2)**: depth mip baking (A)(D) (`WireDepthMipmap.*`, push constant, `MOBILEGL_BAKED_INTERNAL_SHADERS` freshness gate table-driven) and (B′) (the disaggregated build's monolith arm switches to the baked module) landed; the third baked shader set, for multisample resolve, comes with B2; pass-through TCS is still uninventoried. +14. **Which pull-mode-tuned cache hit rates the push model changes.** Survivor capacity is retuned in P13. One clue: on device, 26.3 Espryt's `sve` ≈ draw count (the sampler-view set is re-sent once per draw), while desktop is only ~0.07/draw; on the P3b/P4b optimization list. +15. **Whether monolith's `*IndirectCount` not calling `SyncGpuWrites()` is a latent gap.** A separate `dev` issue; the split must not fix it opportunistically. **Answered (2026-09-30): yes** — P8-C / P8-D host red-once confirms (Espryt `*IndirectCount`, Magma `glMultiDrawArraysIndirectCount` read 0); the split half is fixed (ID-P8-9), and the monolith half is fixed in the P8 second wave's dev package (ID-P8-3). +16. **Actual memory footprint of the index host mirror.** The total element-array buffer in the MC / Sodium / Iris corpora is unmeasured; if it significantly exceeds 64 MiB, the frequency and cost of the fallback path must be measured. P8. +17. **The `create-indirect` fixture's failure on Adreno 830** predates this branch (reproduces with the baseline APK, `dev@81b17c0b`); it is not caused by this branch. The `scudo::reportMapError` crash with `rd12` + Magma on both Adreno 830s is also on the `dev` side. Both are excluded from device A/B and stay in the desktop corpus; P8 must assert `roundtrips-per-frame == 0` on `create-indirect`, so the `dev` fix is on someone else's critical path. **The create-indirect part is answered (2026-09-30)**: the original fixture was captured on a desktop driver with `GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT` = 16, and Flywheel laid out the scatter list for 16; Adreno 830 on both backends and Mali's Vulkan require 64, so all 1,270 range bindings were rejected with `GL_INVALID_VALUE`. The original fixture is retired and replaced by the derived `minecraft-1.21.1-neoforge-create-indirect-in-world-align1024` (**not the same trace**: `tools/trace_replay/fixture_tools/realign_buffer_ranges.cpp --align 1024` moves these bindings to 1024-aligned slots, inserting 3,812 calls, target calls 504631 → 508443; host SSIM matches the original fixture to 9 digits). Redmi passes on both backends for monolith / spawn; on Mali-G1-Ultra Magma passes (the split arm separately fixed the T0 POST, see the POST section of `CONTRACT-P11.md`), while Espryt is still 0.848: that machine's GLES driver vertex-stage SSBO limit is 0, so Flywheel indirect's vertex program cannot link (a missing capability, not a split defect). +18. **Load balancing between the two split sides.** A new question unlocked by P5e: under VD32 (~3550 draws/frame) the apply thread is **11-12 ms**, the client **15.7 ms**, and **the client is the bottleneck, pinned at ~94%**. Moving work from the client to apply would directly lower the bottleneck — meaningless under lockstep (the two sides add serially); **run-ahead is what makes it a lever**. Options: the emitter on the encode side, the tracker walk, dirty-page tracking of the persistent map (`change_protection` was 1.3% in the profile). Must re-profile first: with the waits gone, the denominators of all the tail items have changed. Queued after P5e; unowned; on 2026-09-22 suggested to attach to the optimization phase after the roadmap completes, with the 2×2 matrix lane of P6.5 re-profiling along the way. +19. **Link bandwidth budget and compression.** In the TCP endgame, `SEG_STAGE` bytes/frame is against Wi-Fi / USB (on the order of 30–100 MB/s), not memory; the ~1 MB/frame budget in `ARCHITECTURE.md` §14 at 60 fps is 60 MB/s, already at the Wi-Fi limit. Whether to LZ4-style compress the stage payload and whether to deduplicate texture uploads by content hash on the server side must wait for gate 8's distribution. Must be answered before the first line of the P6.5 contract is written. +20. **The stall of a large single upload.** A 128 MiB single upload at 50 MB/s is 2.5 s; content-side chunking solves "does it fit", not "how long must we wait". On the cross-machine arm, either accept and record it, or make uploads asynchronous (think it through together with P9's semantics). Do not pretend it is solved. +21. **The form of pairing / authentication.** **Ruled (ID-P7-3, 2026-09-22): a token is enough, no TLS.** The threat model is "a remote code path anyone can connect to", not eavesdropping: token comparison in constant time, ≥16 bytes, no token means loopback only, the data plane bound to the authenticated control connection by `Welcome.dataNonce`, authentication before fork. TLS is kept as a P12 open item. +22. **Client platform scope.** The default is Linux + Android first (existing CI can verify), the Windows client in the second batch (`ShmSegmentWin32` exists; the `pipe:` named refusal is retired, TCP replaces it), and macOS is still not split. This decides whether `ARCHITECTURE.md` §15.3 "Windows machines are not a correctness gate" needs changing. +23. **Detection of half-open connections.** A Wi-Fi disconnect does not produce a hang-up event; dl's latch comes from the descriptor hang-up, while TCP needs keepalive / heartbeat timeout and **reporting as a hang-up by the transport layer** — this does not contradict "never take it from an apply timeout"; write it down to avoid re-arguing. P6.5 ct. +24. **Redefinition of the E1 control (ID-122).** **Closed (2026-09-29 debt review)**: `10bfd29f` replaced E1's pixel race with the negative control `scripts/ci/wait_boundary_negative_control.py` that observes protocol waits. On 2026-10-18 that negative control retired: the probe could see the missing wait, so the resident unit case `RemoteWaitBoundaryControl.AnUnwaitedPublishIsSeenAsNoWait` proves it instead (the same `ApplierReset`, no wait after publishing, must read parked=0). diff --git a/docs/Disaggregated/README.md b/docs/Disaggregated/README.md index be755b89..f2789a3a 100644 --- a/docs/Disaggregated/README.md +++ b/docs/Disaggregated/README.md @@ -1,29 +1,29 @@ -# MGPipe:MobileGL 前后端拆分 +# MGPipe: MobileGL frontend/backend split -**做什么**:在 MobileGL 的前端(处理应用的 GL 调用)和后端(调用 GLES / Vulkan 驱动)之间立一份显式接口——前端把状态变化**推**给后端,后端不再直接读前端的内存。有了这份接口,前后端可以放在两个线程、两个进程,甚至两台机器上运行。 +**What it does**: MGPipe puts an explicit interface between MobileGL's frontend (which handles the application's GL calls) and backend (which calls the GLES / Vulkan driver) — the frontend **pushes** state changes to the backend, and the backend no longer reads the frontend's memory directly. With this interface, the frontend and backend can run on two threads, two processes, or even two machines. -**做到哪了**:见 [`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md)。当前阶段与下一步只在那一页维护,这里不再复述。 +**How far along**: see [`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md). The current phase and next steps are maintained only on that page and are not repeated here. -## 一张图 +## One diagram ``` -应用的 GL 调用 - → 前端 MG_Impl:处理 GL 语义;在每条"做事的命令"(draw、clear…)之前,把状态变化整理成记录 - → MGPipe 接口(两张函数指针表,由调用目录 PipeCalls.def 生成) - → 三选一:直接调用(单线程)│ 队列 → 另一个线程 │ 队列 → 另一个进程 / 另一台机器 - → 后端 MG_Backend:Espryt(GLES)/ Magma(Vulkan),按记录更新自己的状态并调用驱动 - ← 反向消息(错误、GPU 写回、窗口尺寸)按顺序回到前端 +The application's GL calls + → frontend MG_Impl: handles GL semantics; before every command that does work (draw, clear…), turns state changes into records + → MGPipe interface (two function pointer tables, generated from the call catalog PipeCalls.def) + → one of three: direct call (single-threaded) │ queue → another thread │ queue → another process / another machine + → backend MG_Backend: Espryt (GLES) / Magma (Vulkan), updates its own state from the records and calls the driver + ← reverse messages (errors, GPU writeback, window size) come back to the frontend in order ``` -## 文档导航 +## Documentation map -| 想知道 | 看 | +| To learn | See | |---|---| -| 现在做到哪、下一步 | [`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md) | -| 设计要点与各部分设计 | [`ARCHITECTURE.md`](ARCHITECTURE.md) → [`design/`](design/) | -| 分几个阶段、每个阶段做了什么 | [`ROADMAP.md`](ROADMAP.md) | -| 性能与验证的关键数字 | [`MEASUREMENTS.md`](MEASUREMENTS.md) | -| 怎么构建、运行、测试 | [`guide/build-and-run.md`](guide/build-and-run.md) | -| 代码在哪 / 术语 / 工程纪律 | [`guide/code-map.md`](guide/code-map.md)、[`guide/glossary.md`](guide/glossary.md)、[`guide/discipline.md`](guide/discipline.md) | +| Where things stand, next steps | [`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md) | +| Key design points and the design of each part | [`ARCHITECTURE.md`](ARCHITECTURE.md) → [`design/`](design/) | +| How many phases there are, what each phase did | [`ROADMAP.md`](ROADMAP.md) | +| Key numbers for performance and verification | [`MEASUREMENTS.md`](MEASUREMENTS.md) | +| How to build, run, and test | [`guide/build-and-run.md`](guide/build-and-run.md) | +| Where the code is / terminology / engineering discipline | [`guide/code-map.md`](guide/code-map.md), [`guide/glossary.md`](guide/glossary.md), [`guide/discipline.md`](guide/discipline.md) | -整理记录:2026-09-24 两次整理——顶层只留索引,设计正文拆到 `design/`,上手与参考放 `guide/`,阶段细节放 `notes/<阶段>/`(这些笔记已从树中删除,见 git 历史);整理前的版本见提交 `1fb18d9`。更早的设计竞赛与评审稿在 git 历史(`8b31de2f`、`1794ac94`、`8349babe`、`87ee17c6`)。 +Organization history: two cleanups on 2026-09-24 — the top level keeps only indexes, the design body moved into `design/`, getting-started and reference material live in `guide/`, and phase details live in `notes//` (those notes have been deleted from the tree; see git history); the pre-cleanup version is commit `1fb18d9`. Earlier design contests and review drafts are in git history (`8b31de2f`, `1794ac94`, `8349babe`, `87ee17c6`). diff --git a/docs/Disaggregated/ROADMAP.md b/docs/Disaggregated/ROADMAP.md index aacc7df0..1145e2ef 100644 --- a/docs/Disaggregated/ROADMAP.md +++ b/docs/Disaggregated/ROADMAP.md @@ -1,46 +1,46 @@ -# 路线图(索引) +# Roadmap (index) -> **2026-10-07**:P0 到 P7、P12、P9、P10、P11、P8、**P13** 已完成——拆分路线与单进程路线都走完。P13(退役 pull 路径):单进程也只走记录臂,pull / push 两套构建、`MOBILEGL_PIPE_PUSH` 与 `MOBILEGL_PIPE_LEGACY_MEMOS` 编译期开关、残余值块和后端的前端对象臂全部删除;库拆成按 link ratchet 分区的七个模块,split 构建里 server 一半单独真链接;G1 退役,由零 `MG_Remote` 符号、skip 普查与 recorder 金标接班;性能工作排在其后,基线是 `dev` 构建。下一项是 **P14**(状态归属)。每个阶段的计划、验收结果、实测与报告见 git 历史。 +> **2026-10-07**: P0 through P7, P12, P9, P10, P11, P8, and **P13** are done — both the split route and the monolith route are complete. P13 (retire the pull path): the monolith also runs only on the record arm; the pull / push builds, the `MOBILEGL_PIPE_PUSH` and `MOBILEGL_PIPE_LEGACY_MEMOS` compile-time switches, the residual value blocks, and the backend's frontend-object arm are all deleted; the library splits into seven modules partitioned by the link ratchet, and in the split build the server half is truly linked on its own; G1 is retired, succeeded by zero `MG_Remote` symbols, the skip census, and the recorder golden. Performance work is queued after it, with the `dev` build as baseline. The next item is **P14** (state ownership). The plan, acceptance results, measured results, and reports for each phase are in git history. -## 目标 +## Goals -client(跑应用的一方)与 server(跑驱动的一方)可以在**不同机器、不同系统**上经 TCP 相连;在同一台机器上则用两个进程 + 共享内存。传输分控制面与数据面两层,可各自选择、混搭。 +The client (the side that runs the application) and the server (the side that runs the driver) can connect over TCP across **different machines and different operating systems**; on the same machine they use two processes + shared memory. The transport has two layers, control plane and data plane, each independently selectable and mixable. -## 两条路线 +## Two routes -- **单进程路线**:先把接口建起来,让单进程版本也受益(后端拥有自己的状态、可以挪到渲染线程)。P0 → P0.5 → P1 → P2 → P3a → P4a → P3b/P4b → P7 → P8 → **P13**(走完)。 -- **拆分路线**:在接口之上逐步拆开前后端。P5 → P5b → P5c → P5d → P5e → P5f → P6 → P6.5 → Ph → P12 → P9 → P10 → **P11**(走完)。 +- **Monolith route**: build the interface first, so the monolith benefits too (the backend owns its own state and can move to the render thread). P0 → P0.5 → P1 → P2 → P3a → P4a → P3b/P4b → P7 → P8 → **P13** (complete). +- **Split route**: split the frontend and backend step by step on top of the interface. P5 → P5b → P5c → P5d → P5e → P5f → P6 → P6.5 → Ph → P12 → P9 → P10 → **P11** (complete). -## 阶段一览 +## Phase list -| 阶段 | 做什么 | 状态 | +| Phase | What it does | Status | |---|---|---| -| P0 | 打地基:计数器、调用目录与生成器、CI 门;验证 Android 能拉起第二个进程 | ✅ 09-05 | -| P0.5 | 抽出前后端共用的数据类型头,切断后端对前端头文件的依赖 | ✅ | -| P1 | 后端改读一个"输入块",并能逐 draw 核对它与前端真实状态一致 | ✅ | -| P2 | 前端开始主动推送渲染状态;接口代价实测 +6–12%,决定继续 | ✅ 09-08 | -| P3a | GLES 后端的 buffer、顶点数组改用句柄 | ✅ 09-08 | -| P4a | GLES 后端的帧缓冲、纹理、sampler、program 改用句柄 | ✅ 09-08 | -| P5 | 第一次拆成两线程:命令队列 + 后端线程(每条命令都等) | ✅ 09-16 | -| P5b | 把剩余命令迁到队列上;真机首次以独立后端线程跑通目标游戏 | ✅ 09-16 | -| P5c | 两线程之间不再偷偷共享内存,只经队列交换 | ✅ 09-17 | -| P5d | 两线程版本的性能:游戏内 7–13 fps → 103–106 fps | ✅ 09-18 | -| P5e | client 发完就走,不再每条命令等后端;重负载下与单线程持平 | ✅ 09-19 | -| P5f | 所有状态都经队列传递,为拆进程扫清最后障碍;Vulkan 后端也能发完就走 | ✅ 09-20 | -| P6 | 拆成两个进程;真机上两进程与两线程成本持平 | ✅ 09-22 | -| P6.5 | 传输分控制面 / 数据面;电脑当 client、手机当 server 经 TCP 跑通 | 第一波 ✅,余项交 CI | -| Ph | server 能安全地接受外来连接:令牌、限额、坏数据不致崩溃 | 必需项 ✅(随 P7) | -| P3b / P4b | GLES 后端的深化与收尾 | 大部分 ✅,余项并行 | -| P7 | Vulkan 后端完整迁移;真机画面检查 36/36 通过 | ✅ 09-23 | -| **P12** | **server 自己开窗口上屏,client 不需要窗口** | ✅ 09-29:出口门 B(跨机 TCP)✅ 09-28、A(FCL + 杀 server)✅ 09-29;契约见 git 历史;G1 成立;余项进 [`DEBTS.md`](DEBTS.md) | -| **P8** | ~~把剩余的仿真路径挪到正确的一侧,补齐协议~~ → **补齐 server 侧仿真缺口与 split 覆盖** | ✅ 09-30:重定界(原 10 项里 6 项前序已完成);Espryt 生成 mip / 暂存副本与 GPU 写 / 驱动拒读、Magma wire 原生 indirect 与 dispatch;246 例登上 split 三臂(`split_coverage.py`);Create 在 Adreno 上的丢拷贝修到 dev 与 feat;契约见 git 历史;余项进 [`DEBTS.md`](DEBTS.md) | -| **P9** | **反向通道:回读、日志、重铸不再同步等待 client** | ✅ 09-29:PACK-PBO 回读 fire-and-forget(两后端)、日志分级转发、重铸无拉取(`OnLog` / `OnTexturePullRequest` 删,回调 9 → 7),F1 / F2;契约见 git 历史;G1 成立;事件量批处理无实测需求不做;余项进 [`DEBTS.md`](DEBTS.md) | -| **P10** | **同步对象、查询与帧节奏** | ✅ 09-29:fence 轮询由 server 报告本地作答(`kEventFenceSignaled`、`MOBILEGL_IPC_POLL_ESCALATE`;主机 Magma·tcp −37%,Adreno 830 上两后端 0 次往返);`SetSwapInterval` 转发、class C 清零;query / XFB / AsyncCompile 登记 split 各臂;credit 1/2/3 设备 loopback 在噪声内;契约见 git 历史;G1 成立;余项进 [`DEBTS.md`](DEBTS.md) | -| **P11** | **同机大缓冲零拷贝共享** | ✅ 09-29:T0 零拷贝导入(两后端,默认开,自测不过或 Stream 上静默退回 T2);同机外部 client 经 helper + 令牌 broker 走共享内存(B1);连接按 `PairBind` nonce 配对(修订 5);采纳档位在握手时定;契约见 git 历史;余项进 [`DEBTS.md`](DEBTS.md) | -| **P13** | **删掉旧的"后端直接读前端"路径** | ✅ 10-07:单进程只走记录臂;pull / push 构建与 `PIPE_PUSH` / `LEGACY_MEMOS` 编译期开关、残余值块、后端前端对象臂删除;七个 OBJECT 模块与 server-only 真链接;link ratchet 172 → 27 具名债务;recorder 金标;G1 退役;FCL 真机两后端冒烟通过;性能轮(基线 `dev`)与余项进 [`DEBTS.md`](DEBTS.md) | -| **P14** | **状态归属:同进程多 session / 多 context / share group**(统一 server 的前提,anland 内置渲染器不做按进程隔离) | 设计 ✅ [`design/11-state-ownership.md`](design/11-state-ownership.md),实现待做 | +| P0 | Lay the foundation: counters, call catalog and generators, CI gates; verify Android can launch a second process | ✅ 09-05 | +| P0.5 | Extract the data type header shared by frontend and backend, cutting the backend's dependency on frontend headers | ✅ | +| P1 | The backend reads an "input block" instead, and can verify per draw that it matches the frontend's real state | ✅ | +| P2 | The frontend starts actively pushing render state; interface cost measured at +6–12%, decision to continue | ✅ 09-08 | +| P3a | GLES backend's buffers and vertex arrays switch to handles | ✅ 09-08 | +| P4a | GLES backend's framebuffers, textures, samplers, programs switch to handles | ✅ 09-08 | +| P5 | First split into two threads: command queue + backend thread (every command waits) | ✅ 09-16 | +| P5b | Move the remaining commands onto the queue; first on-device run of the target game with a separate backend thread | ✅ 09-16 | +| P5c | The two threads no longer secretly share memory; they exchange only through the queue | ✅ 09-17 | +| P5d | Two-thread performance: in-game 7–13 fps → 103–106 fps | ✅ 09-18 | +| P5e | The client runs ahead and no longer waits for the backend on every command; matches single-threaded under heavy load | ✅ 09-19 | +| P5f | All state passes through the queue, clearing the last obstacle to splitting into processes; the Vulkan backend also runs ahead | ✅ 09-20 | +| P6 | Split into two processes; on device the two-process cost matches two-thread | ✅ 09-22 | +| P6.5 | Transport splits into control plane / data plane; a PC as client and a phone as server run over TCP | first wave ✅, remainder to CI | +| Ph | The server safely accepts external connections: token, quotas, bad data does not crash | required items ✅ (with P7) | +| P3b / P4b | Deepening and wrap-up of the GLES backend | mostly ✅, remainder in parallel | +| P7 | Full Vulkan backend migration; on-device frame check 36/36 passes | ✅ 09-23 | +| **P12** | **The server opens its own window and presents on screen; the client needs no window** | ✅ 09-29: exit gate B (cross-machine TCP) ✅ 09-28, A (FCL + killing the server) ✅ 09-29; contract in git history; G1 holds; remainder into [`DEBTS.md`](DEBTS.md) | +| **P8** | ~~Move the remaining emulation paths to the correct side and complete the protocol~~ → **Close the server-side emulation gaps and split coverage** | ✅ 09-30: re-scoped (6 of the original 10 items were already done as prerequisites); Espryt mip generation / staging copies with GPU writes / driver refusing reads, Magma wire-native indirect and dispatch; 246 cases brought onto the split three arms (`split_coverage.py`); the Create dropped-copy fix on Adreno landed in dev and feat; contract in git history; remainder into [`DEBTS.md`](DEBTS.md) | +| **P9** | **Reverse channel: readback, logs, and re-mint no longer wait synchronously for the client** | ✅ 09-29: PACK-PBO readback fire-and-forget (both backends), graded log forwarding, re-mint without pull (`OnLog` / `OnTexturePullRequest` deleted, callbacks 9 → 7), F1 / F2; contract in git history; G1 holds; event-volume batching not done, no measured need; remainder into [`DEBTS.md`](DEBTS.md) | +| **P10** | **Synchronization objects, queries, and frame pacing** | ✅ 09-29: fence polling answered locally by the server's own report (`kEventFenceSignaled`, `MOBILEGL_IPC_POLL_ESCALATE`; host Magma·tcp −37%, zero round trips for both backends on Adreno 830); `SetSwapInterval` forwarded, class C zeroed; query / XFB / AsyncCompile registered on each split arm; credit 1/2/3 device loopback within noise; contract in git history; G1 holds; remainder into [`DEBTS.md`](DEBTS.md) | +| **P11** | **Same-machine large-buffer zero-copy sharing** | ✅ 09-29: T0 zero-copy import (both backends, on by default, silently falls back to T2 when the self-test fails or on Stream); same-machine external client goes through shared memory via helper + token broker (B1); connections paired by `PairBind` nonce (revision 5); adoption tier fixed at handshake; contract in git history; remainder into [`DEBTS.md`](DEBTS.md) | +| **P13** | **Delete the old "backend reads the frontend directly" path** | ✅ 10-07: the monolith runs only on the record arm; the pull / push builds and the `PIPE_PUSH` / `LEGACY_MEMOS` compile-time switches, the residual value blocks, and the backend's frontend-object arm are deleted; seven OBJECT modules and server-only real linking; link ratchet 172 → 27 named debts; recorder golden; G1 retired; FCL on-device smoke passes on both backends; performance round (baseline `dev`) and remainder into [`DEBTS.md`](DEBTS.md) | +| **P14** | **State ownership: multiple sessions / multiple contexts / share groups in one process** (prerequisite for a unified server; anland's built-in renderer does not isolate per process) | design ✅ [`design/11-state-ownership.md`](design/11-state-ownership.md), implementation pending | -## 另见 +## See also -- 工程纪律与验证门:[`guide/discipline.md`](guide/discipline.md) -- 仍开放的债务:[`docs/Disaggregated/DEBTS.md`](DEBTS.md);开放问题:[`docs/Disaggregated/OPEN-QUESTIONS.md`](OPEN-QUESTIONS.md) +- Engineering discipline and verification gates: [`guide/discipline.md`](guide/discipline.md) +- Still-open debts: [`docs/Disaggregated/DEBTS.md`](DEBTS.md); open questions: [`docs/Disaggregated/OPEN-QUESTIONS.md`](OPEN-QUESTIONS.md) diff --git a/docs/Disaggregated/design/01-boundary-and-objects.md b/docs/Disaggregated/design/01-boundary-and-objects.md index c4d3384a..160bd35c 100644 --- a/docs/Disaggregated/design/01-boundary-and-objects.md +++ b/docs/Disaggregated/design/01-boundary-and-objects.md @@ -1,58 +1,58 @@ -# 边界与对象模型(原 ARCHITECTURE §1–§2) +# Boundary and Object Model (formerly ARCHITECTURE §1–§2) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design highlights and an index of all sections are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; `ARCHITECTURE.md §N` in code comments resolves by number here. -## 1. 边界 +## 1. Boundary -### 1.1 一句话 +### 1.1 In one sentence -`MG_Backend` 本来就是一台贴着目标 API 的状态机(Espryt = DirectGLES,Magma = DirectVulkan),缺的是一份"我被告知了什么"的显式声明。MGPipe 就是这份声明:前端在每条 verb 之前把变化**推**过去,后端不再拉 `MG_State::pGLContext`。接口从两个后端自己维护的关键结构反推(`SetupDrawSnapshot`、`DrawTextureSyncKeys`、`ResolvedVertexBindings`、`g_syncedRenderStateParameters`、`BufferBackendOps` …);gallium 是词汇的目的地,不是推导前提。 +`MG_Backend` was already a state machine glued to the target API (Espryt = DirectGLES, Magma = DirectVulkan); what it lacked was an explicit declaration of "what I was told". MGPipe is that declaration: the frontend **pushes** changes across before every verb, and the backend no longer pulls `MG_State::pGLContext`. The interface is derived backward from the key structures the two backends maintain themselves (`SetupDrawSnapshot`, `DrawTextureSyncKeys`, `ResolvedVertexBindings`, `g_syncedRenderStateParameters`, `BufferBackendOps` …); gallium is where the vocabulary is headed, not a premise of the derivation. -### 1.2 两张函数指针表 +### 1.2 Two function pointer tables -`MGPipeScreen`(share-group 作用域:caps、resource、persistent map、fence)与 `MGPipeContext`(其余全部),由 `PipeCalls.def` 生成。 +`MGPipeScreen` (share-group scope: caps, resource, persistent map, fence) and `MGPipeContext` (everything else), generated from `PipeCalls.def`. -- 函数指针 struct 而非虚基类:null 项已表示"未实现,前端回退",`MG_Test` 整表替换即可 mock。 -- 两张表从第一天分开,事后拆会给记录重新编号;v1 只有一个 screen、一个 context、一条 flow。 -- EGL 生命周期与 caps 面留在 `pActiveBackendObject` 的虚函数上(罕见路径,走控制面)。 +- A struct of function pointers instead of a virtual base class: a null entry already means "not implemented, the frontend falls back", and `MG_Test` can mock the whole thing by replacing the table. +- The two tables are separate from day one; splitting them later would renumber the records; v1 has only one screen, one context and one flow. +- EGL lifecycle and the caps side stay on the virtual functions of `pActiveBackendObject` (a rare path, on the control plane). -### 1.3 三种形态,一份后端 +### 1.3 Three forms, one backend -| 形态 | 表里装的是什么 | 用途 | +| Form | What the tables hold | Purpose | |---|---|---| -| `monolith`(默认) | 后端自己的函数,回调直调 `MG_State` | 出货 | -| `inproc` | 发射器 → 同进程第二个线程上的 applier | CI 主验收;也就是 monolith 的**渲染线程** | -| `spawn` | 发射器 → 数据面 → 另一个进程的 applier → 同一批后端函数 | 两进程形态;控制面可以是 `fork` / `unix:` / `tcp://`(§11.9),server 可在另一台机器上 | +| `monolith` (default) | the backend's own functions; callbacks call `MG_State` directly | ship | +| `inproc` | emitter → applier on a second thread in the same process | CI main acceptance; that is, the monolith **render thread** | +| `spawn` | emitter → data plane → applier in another process → the same set of backend functions | two-process form; the control plane can be `fork` / `unix:` / `tcp://` (§11.9), and the server can be on another machine | -唯一 hook 点是 `MG_Backend::Init()` 里一个 `#if MOBILEGL_BUILD_DISAGGREGATED` 分支:`MG_Config::Transport != Monolith` 时装 `MG_Remote::BackendObject_Remote`。`MG_Impl` 的边界调用点零 `#ifdef`。 +The only hook point is one `#if MOBILEGL_BUILD_DISAGGREGATED` branch inside `MG_Backend::Init()`: when `MG_Config::Transport != Monolith` it installs `MG_Remote::BackendObject_Remote`. Zero `#ifdef`s at `MG_Impl`'s boundary call sites. -## 2. 对象模型 +## 2. Object model -### 2.1 句柄 = `{slot, gen}`(`MG_Pipe/MGPipeHandles.h`) +### 2.1 Handle = `{slot, gen}` (`MG_Pipe/MGPipeHandles.h`) -- 8 字节 POD;**client 铸造,server 永不返回句柄** → 整份目录零创建 round trip(对 gallium 的偏离 D1)。 -- slot 按 kind 稠密分配(free list + 高水位),server 对象表是数组;`gen` 只在 slot 复用时 ++。 -- kind:`Buffer, Texture, Renderbuffer, Framebuffer, Xfb, RenderStateCso, VertexElementsCso, SamplerCso, SamplerViewCso, ShaderCso, Fence, Query, Context`。保留:`{0,0}` = null;`Framebuffer {0,1}` = 默认帧缓冲;`ShaderCso` 高段给 program pipeline 合成体。 -- GL name 只作诊断(`GlNameForDiag`),永不做身份、memo 键或 content hash。 +- An 8-byte POD; **the client mints it, the server never returns a handle** → the whole catalog has zero creation round trips (deviation D1 from gallium). +- Slots are allocated densely per kind (free list + high-water mark), the server's object table is an array; `gen` is incremented only when a slot is reused. +- kind: `Buffer, Texture, Renderbuffer, Framebuffer, Xfb, RenderStateCso, VertexElementsCso, SamplerCso, SamplerViewCso, ShaderCso, Fence, Query, Context`. Reserved: `{0,0}` = null; `Framebuffer {0,1}` = the default framebuffer; the high segment of `ShaderCso` is for program pipeline composites. +- GL names are for diagnostics only (`GlNameForDiag`), never for identity, memo keys or content hashes. -### 2.2 两种世代,严格分开 +### 2.2 Two kinds of generation, strictly separated -| | 拥有者 | 回答 | 过线 | +| | Owner | Answers | Crosses the wire | |---|---|---|---| -| `MGPipeHandle::Gen` | client | "还是同一个 GL 对象吗?" | 是 | -| `MGGen`(后端纪元,如 `g_bufferMutationEpoch`) | server | "我自己是否重铸了驱动对象?" | **永不**(只以纹理拉取请求的形式出现,§8.4) | +| `MGPipeHandle::Gen` | client | "Is it still the same GL object?" | yes | +| `MGGen` (backend epoch, e.g. `g_bufferMutationEpoch`) | server | "Did I re-mint the driver object myself?" | **never** (it appears only in the form of a texture pull request, §8.4) | -client 的回绕 `Uint16` 版本计数器永远不是新鲜度的唯一证明:过线时要么加宽,要么与 `{slot, gen}` 同行。 +The client's wrapping `Uint16` version counter is never the sole proof of freshness: when it crosses the wire, either widen it or send it alongside `{slot, gen}`. -### 2.3 CSO 与可变对象 +### 2.3 CSO and mutable objects -- CSO(render state、vertex elements、sampler、sampler view、shader)在 **client 侧内容寻址**(Mesa `cso_cache` 先例),LRU 淘汰时发 `delete_*`;render-state 容量 64(P13 重调)、sampler state 256。 -- Buffer / Texture / Renderbuffer 走 create / respecify / subdata / destroy;Framebuffer / Xfb 是 per-context 身份 + `set_*` payload。 -- 两条偏离:**D-G1** Espryt 的 vertex-elements 按 VAO 身份寻址(twin 持驱动 VAO 名,不能共享);**D-F2** Espryt 的 sampler view 按纹理身份寻址,sampler state 内容寻址且带引用计数(被 `BuiltinSampler` 指着的项不许被 LRU 挤掉)。 +- CSO (render state, vertex elements, sampler, sampler view, shader) is **content-addressed on the client side** (Mesa `cso_cache` precedent), and sends `delete_*` on LRU eviction; render-state capacity 64 (retuned in P13), sampler state 256. +- Buffer / Texture / Renderbuffer go through create / respecify / subdata / destroy; Framebuffer / Xfb are per-context identity + `set_*` payload. +- Two deviations: **D-G1** Espryt's vertex elements are addressed by VAO identity (the twin holds the driver VAO name and cannot be shared); **D-F2** Espryt's sampler view is addressed by texture identity, sampler state is content-addressed and reference-counted (an entry pointed to by a `BuiltinSampler` must not be evicted by the LRU). -#### 2.3.1 sampler state 缓存:引用计数与值生命周期 +#### 2.3.1 sampler state cache: reference counting and value lifetime -sampler state 在 client 侧按值寻址(`MGPipeSamplerCsoCache`,容量 256):哈希、探测、再 memcmp 确认;只凭 64 位哈希相等会把两种状态并进一个 CSO,造成没有门看得见的错误过滤。 -- 活句柄躲开 LRU 靠引用计数而不是容量:已发布的 `MGPTextureParams` 在纹理参数不动时一直指着它的 `BuiltinSampler`,applier 不解析这个句柄,而淘汰不算参数变化,既不会重发也没人拒绝。所以每次 `Acquire` 取一个引用、`Release` 还一个;LRU 只考虑引用为 0 的项;全被钉住时超容量铸造并计入 `OverCapacityMints`(多一个槽费内存,句柄被抽走费正确性)。 -- 持有引用的是纹理的内建 sampler(纹理死亡或参数变化重取时释放)和 `bind_sampler_states` 当前绑定的每个 CSO;凡在返回后还会指名该句柄的调用方都必须持有。容量大于 `kMGPipeMaxTextureUnits` 只是尺寸界:装不下一整轮发射的缓存会每轮都超容量铸造。 -- 槽不带 lifetime id:CSO 属于值而不属于前端对象(别的 `SamplerObject` 可能持有同值),`~SamplerObject` 不释放任何槽,唯一死亡路径是 client 侧的 LRU 淘汰。因此来自 `~SamplerObject` 的 `NotifyStateObjectDestroyed(SamplerCso, lifetimeId)` 背后永远没有句柄;后端不得按 `SamplerObject` 的 lifetime id 键控 sampler twin,twin 的生命只是 `create_sampler_state` 到 LRU 发出的 `delete_sampler_state`。 +sampler state is value-addressed on the client side (`MGPipeSamplerCsoCache`, capacity 256): hash, probe, then confirm with memcmp; trusting a 64-bit hash match alone would merge two states into one CSO, causing incorrect filtering that no gate can see. +- Live handles avoid the LRU by reference count rather than by capacity: a published `MGPTextureParams` keeps pointing at its `BuiltinSampler` while the texture parameters do not change, the applier does not resolve this handle, and eviction does not count as a parameter change, so the handle is neither re-sent nor rejected. Therefore every `Acquire` takes a reference and `Release` returns one; the LRU considers only entries with zero references; when everything is pinned and capacity is exceeded, mint beyond capacity and count it in `OverCapacityMints` (an extra slot costs memory, a stolen handle costs correctness). +- The holders are the texture's built-in sampler (released when the texture dies or when parameters change and it re-acquires) and every CSO currently bound by `bind_sampler_states`; any caller that will still name the handle after returning must hold one. Capacity greater than `kMGPipeMaxTextureUnits` is only a size bound: a cache that cannot hold one full round of emission will mint beyond capacity every round. +- Slots carry no lifetime id: a CSO belongs to a value, not to a frontend object (another `SamplerObject` may hold the same value), `~SamplerObject` frees no slot, and the only death path is client-side LRU eviction. So a `NotifyStateObjectDestroyed(SamplerCso, lifetimeId)` coming from `~SamplerObject` never has a handle behind it; the backend must not key sampler twins by a `SamplerObject`'s lifetime id; a twin's life is only from `create_sampler_state` to the `delete_sampler_state` issued by the LRU. diff --git a/docs/Disaggregated/design/02-catalogue-and-records.md b/docs/Disaggregated/design/02-catalogue-and-records.md index 94f16291..ecd94a89 100644 --- a/docs/Disaggregated/design/02-catalogue-and-records.md +++ b/docs/Disaggregated/design/02-catalogue-and-records.md @@ -1,76 +1,76 @@ -# 调用目录与记录格式(原 ARCHITECTURE §3–§4) +# Call Catalog and Record Format (formerly ARCHITECTURE §3–§4) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design highlights and an index of all sections are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; `ARCHITECTURE.md §N` in code comments resolves by number here. -## 3. 调用目录 +## 3. Call catalog -### 3.1 单一真相源 +### 3.1 Single source of truth -`MobileGL/MG_Pipe/PipeCalls.def`:一行一个 `X(Name, Payload, Class, Flags, WaitClass)`。**线上 opcode 就是行序**,只能追加、退役保留槽位;行数由 `MGP_CALL_LIST_DOCUMENTED_COUNT`(今天 81)与 `PipeCatalogueTest` 钉住。生成器产物提交进树,CI `pipe-gates` 重生成并 `git diff --exit-code`: +`MobileGL/MG_Pipe/PipeCalls.def`: one `X(Name, Payload, Class, Flags, WaitClass)` per line. **The on-wire opcode is the line order**; you can only append, and retired lines keep their slot; the line count is pinned by `MGP_CALL_LIST_DOCUMENTED_COUNT` (81 today) and `PipeCatalogueTest`. Generator outputs are committed to the tree; CI `pipe-gates` regenerates them and runs `git diff --exit-code`: -| | 产物 | 内容 | +| | Output | Content | |---|---|---| -| G1 | `PipeTables.inc` | 两张函数指针表 | -| G2 | `PipeThunks.inc` | monolith 直调 thunk | -| G3 | `PipeWire.inc` | wire 记录、尺寸 `static_assert`、applier 边界检查 | -| G4 | `PipeVerify.inc` | `MOBILEGL_PIPE_VERIFY` 逐字段比对器(`PipeFields.def`) | -| G5 | `PipeFilled.inc` | `PipeInputs` 字段 id 与逐 verb 世代 poison | -| G6 | `PipeCoverage.inc` | 后端读点 → 调用映射(`Coverage.def`),0 UNMAPPED 是门 | -| G7 | `PipeSpanTable.inc` | render-state pipeline 子集成员表 | -| G8 | `PipeFieldOwnership.inc` | 每个 `PipeInputs` 字段恰属 `RECORD-SUPPLIED / APPLIER-DERIVED / BARRIER-PULLED / FATAL` 之一(P5f 起 0 BARRIER-PULLED) | +| G1 | `PipeTables.inc` | the two function pointer tables | +| G2 | `PipeThunks.inc` | monolith direct-call thunks | +| G3 | `PipeWire.inc` | wire records, size `static_assert`s, applier bounds checks | +| G4 | `PipeVerify.inc` | `MOBILEGL_PIPE_VERIFY` field-by-field comparator (`PipeFields.def`) | +| G5 | `PipeFilled.inc` | `PipeInputs` field ids and per-verb generation poison | +| G6 | `PipeCoverage.inc` | backend read sites → call mapping (`Coverage.def`); 0 UNMAPPED is the gate | +| G7 | `PipeSpanTable.inc` | render-state pipeline subset membership table | +| G8 | `PipeFieldOwnership.inc` | each `PipeInputs` field belongs to exactly one of `RECORD-SUPPLIED / APPLIER-DERIVED / BARRIER-PULLED / FATAL` (0 BARRIER-PULLED since P5f) | -另有 `FillPoints.def`(填充点)与 `DirtySurface.def`(§5.2)。G1 codegen 规则:capability gate 替换指针表达式时保留**表达式形状**,否则 pull `.text` 漂移。 +There are also `FillPoints.def` (fill points) and `DirtySurface.def` (§5.2). G1 codegen rule: when the capability gate replaces a pointer expression, preserve the **expression shape**, otherwise the pull `.text` drifts. -### 3.2 分组与 flag +### 3.2 Groups and flags -- Class:`kScreen`(caps、resource、persistent map、fence、`ApplierReset`)、`kCtxQuery`、`kCtxCso`(create/bind/delete × 五种 CSO)、`kCtxState`(`Set*` 状态、`SetContextValues`、`SetProgramBindings`、迁移期的 `SetResidualValueState`)、`kCtxObject`(subdata、readback、mip、`ObjectDeath` …)、`kCtxVerb`(blit、clear、`DrawVbo`、dispatch、XFB、`Present` …)。 -- Flags:`kNeedsAck`、`kHasBlob`、`kVarTail`、`kHostSpan`、`kReplySlot`、`kOptional`。第五列 `WaitClass`(P5e)决定 run-ahead 下 client 等不等(§11.6)。 -- 20 个 draw 入口塌成 `DrawVbo` 一条;`Clear` 一条判别式;sampler 集合**没有 stage 维度**(192 单元合并空间);`SetTextureParams` 按资源寻址、与 sampler view 分开(D10);`SetIndexBuffer` 独立于 VAO 配置(D5)。 -- 显式不移植:`GetIntegeri_v` / `GetInteger64i_v` / `GetProgramiv`、`set_pixel_unpack_state`(前端已解析)、压缩格式概念、`pipe_transfer`。 +- Class: `kScreen` (caps, resource, persistent map, fence, `ApplierReset`), `kCtxQuery`, `kCtxCso` (create/bind/delete × five kinds of CSO), `kCtxState` (`Set*` state, `SetContextValues`, `SetProgramBindings`, `SetResidualValueState` during migration), `kCtxObject` (subdata, readback, mip, `ObjectDeath` …), `kCtxVerb` (blit, clear, `DrawVbo`, dispatch, XFB, `Present` …). +- Flags: `kNeedsAck`, `kHasBlob`, `kVarTail`, `kHostSpan`, `kReplySlot`, `kOptional`. The fifth column, `WaitClass` (P5e), decides whether the client waits under run-ahead (§11.6). +- The 20 draw entry points collapse into the single `DrawVbo`; `Clear` is a single discriminative call; the sampler set **has no stage dimension** (a merged 192-unit space); `SetTextureParams` is resource-addressed and separate from sampler views (D10); `SetIndexBuffer` is independent of VAO configuration (D5). +- Deliberately not ported: `GetIntegeri_v` / `GetInteger64i_v` / `GetProgramiv`, `set_pixel_unpack_state` (the frontend already resolves it), the compressed format concept, `pipe_transfer`. -#### 3.2.1 flag 与 WaitClass 的含义 +#### 3.2.1 Meaning of the flags and WaitClass -- `kHasBlob` 严格表示 payload 拥有一个 `MGPBlobRef` 成员,而不是"这条调用带字节":解码器信任它就必须有成员可读。`ResourceRespecify` 的初始内容与 `ResourceFlushRange` 的字节不走 blobref,而以相邻的 `resource_subdata` 记录过线。 -- `kNeedsAck` 只表示这条调用的记录**可能**要 ack,由逐记录谓词决定(`MGPipeResourceRespecifyNeedsAck`,§8.3)。 -- `kReplySlot`:applier 返回 client 会据以动作的答案(清 level 脏标、闩参数)。flag 只导出一份 `kMGPipeCallFlags[]`(`generated/PipeWire.inc`),消费者不另抄。 -- 第五列 `WaitClass` 是值不是 opcode,生成为 `MGPipeWaitClassFor(op)`,是 `MGPipeBarriered`(§11.6)的静态一项;client 只在 run-ahead 武装(server 发布 `kCapRunAheadApply`)时据它决定等不等,否则走 lockstep: - - `kWaitReply`:答案不可推导且 client 要用,阻塞在 reply slot。与 `kReplySlot` 同在同缺,`gen_pipe.py` 拒绝不一致的行:不等的 reply 行会让 client 读一个没人填的 slot,没有 slot 的等待行会等一个没人发的答案。逐记录 route 谓词可再放宽(如 `MGPipeSubDataWantsItsReply`)。 - - `kWaitPresent`:节奏由 encode 之前取的 present credit 决定,publish 之后不再等。 - - `kWaitApplied`:client 停到记录 apply 完(今天只有 `applier_reset`)。 - - `kWaitNone`:apply 不读 client 内存,发布即走。 +- `kHasBlob` strictly means the payload owns an `MGPBlobRef` member, not "this call carries bytes": if the decoder trusts it, there must be a member to read. The initial contents of `ResourceRespecify` and the bytes of `ResourceFlushRange` do not go through a blobref; they cross the wire as an adjacent `resource_subdata` record. +- `kNeedsAck` only means this call's record **may** need an ack, decided by a per-record predicate (`MGPipeResourceRespecifyNeedsAck`, §8.3). +- `kReplySlot`: the applier returns an answer the client will act on (clearing level dirty bits, latching parameters). The flag exports only one `kMGPipeCallFlags[]` (`generated/PipeWire.inc`); consumers do not copy it. +- The fifth column, `WaitClass`, is a value rather than an opcode, generated as `MGPipeWaitClassFor(op)`, one static entry of `MGPipeBarriered` (§11.6); the client uses it to decide whether to wait only when run-ahead is armed (the server publishes `kCapRunAheadApply`); otherwise it goes lockstep: + - `kWaitReply`: the answer is not derivable and the client needs it, so block on the reply slot. It is present and absent together with `kReplySlot`, and `gen_pipe.py` rejects inconsistent lines: a reply line that does not wait would make the client read a slot nobody fills; a waiting line with no slot would wait for an answer nobody sends. A per-record route predicate can relax this further (e.g. `MGPipeSubDataWantsItsReply`). + - `kWaitPresent`: the pace is decided by the present credit taken before encoding, and there is no waiting after publish. + - `kWaitApplied`: the client stops until the record has been applied (today only `applier_reset`). + - `kWaitNone`: apply does not read client memory, so publish and go. -### 3.3 能力位(`MGPCapBit`) +### 3.3 Capability bits (`MGPCapBit`) -`CallMask` 取代"槽位是否为 null"这一隐式能力探测;`MGPCaps` = `DynamicBackendParameters` + `CallMask` + 格式能力表与 renderer 字符串两个 blob,握手后快照、`MakeCurrent` / `InitCapabilities` 后按 generation 重发布。位包括 viewport array、fp64 顶点、`kCapResidentSubData`、XFB / query 家族、`kCapNeedsHostIndexBytes`、`kCapNeedsHostUboBytes`、`kCapBackendOwnsXfbCapture`、`kCapRunAheadApply`(`MGPipeRunAheadCapBitsFor`:Espryt 自 P5e、Magma 自 P5f 之后的 Magma run-ahead 起发布,后者契约见 git 历史)。**不存在"归属开关"(D-B7)**:multi-draw 分档与 restart 重写永远由 server 拥有,client 只在 caps 要求时提供索引字节。 +`CallMask` replaces the implicit capability probe of "is the slot null"; `MGPCaps` = `DynamicBackendParameters` + `CallMask` + two blobs, the format capability table and the renderer string; snapshotted after the handshake, republished per generation after `MakeCurrent` / `InitCapabilities`. The bits include viewport array, fp64 vertices, `kCapResidentSubData`, the XFB / query family, `kCapNeedsHostIndexBytes`, `kCapNeedsHostUboBytes`, `kCapBackendOwnsXfbCapture`, `kCapRunAheadApply` (`MGPipeRunAheadCapBitsFor`: Espryt since P5e, and Magma run-ahead since P5f, whose contract is in the git history). **There is no "ownership switch" (D-B7)**: multi-draw tiering and restart rewriting always belong to the server, and the client supplies index bytes only when the caps ask for them. -## 4. 记录与 payload 约定(`MG_Pipe/MGPipeTypes.h`) +## 4. Record and payload conventions (`MG_Pipe/MGPipeTypes.h`) -- 每个 payload 是平坦 POD、显式 padding、`static_assert` 精确尺寸;**永不含指针**。 -- `MGPBlobRef{Offset, Size, Seg}` 指向 blob 区;`MGHostSpan` 是唯一随传输而变的形状(monolith 下是指针,split 下字节在 `SEG_STAGE`),只进变长尾。 -- wire 记录头 `MGPWireRecHeader{Op, Flags, Size}`(8 B);**没有逐记录序号**,seq 就是记录序数。 -- 单条记录上界 = ring 一半,**记录本身永不分块**(R-10);**内容侧分块**:会超出 `SEG_STAGE` 的 blob 按 `MGPipeStageChunkBytes()`(默认 segment/4 = 8 MiB)切成多条记录(buffer 范围走查、纹理整宽 slab,server 拼回整级)。 +- Each payload is a flat POD with explicit padding and a `static_assert` on the exact size; **it never contains pointers**. +- `MGPBlobRef{Offset, Size, Seg}` points into the blob area; `MGHostSpan` is the only shape that changes with the transport (a pointer under monolith, bytes in `SEG_STAGE` under split), and it only goes into the variable-length tail. +- The wire record header `MGPWireRecHeader{Op, Flags, Size}` (8 B); **there is no per-record sequence number**, the seq is the record ordinal. +- The upper bound of a single record is half the ring, and **a record itself is never chunked** (R-10); **content is chunked**: a blob that would exceed `SEG_STAGE` is split by `MGPipeStageChunkBytes()` (default segment/4 = 8 MiB) into several records (buffer range walks, full-width texture slabs; the server reassembles the whole level). -### 4.1 关键 payload +### 4.1 Key payloads -| payload | 要点 | +| payload | Key points | |---|---| -| `MGPResourceDesc` | buffer / 纹理 / renderbuffer 一个判别式 create/respecify 形状;`ImageBindableHint`、`ViewOf`(视图的存储属主)、`HasDefinedContent` | +| `MGPResourceDesc` | one discriminative create/respecify shape for buffer / texture / renderbuffer; `ImageBindableHint`, `ViewOf` (the storage owner of a view), `HasDefinedContent` | | `MGPRenderStateDesc` / `MGPBindRenderState` / `MGPDynamicState` | §5.3 | -| `MGPVertexElements` | blob 同时带解析后的属性与绑定点视图(记录自洽) | -| `MGPSamplerView` / `MGPTextureParams` | view 只带视图限制;纹理参数挂纹理对象,`BuiltinSampler` 句柄不许为空(D-E1) | -| `MGPProgramDesc` | 逐 stage SPIR-V + 反射归档(§7) | -| `MGPFramebufferState` | 8 color + depth + stencil + client 解析后的 read surface;`ContentHash` 同时是 render-pass memo 键与发射抑制器;`Target` 含 `Named = 3`,applier 按 framebuffer 句柄存 | +| `MGPVertexElements` | the blob carries both the parsed attributes and the binding-point views (the record is self-consistent) | +| `MGPSamplerView` / `MGPTextureParams` | a view carries only view restrictions; texture parameters hang off the texture object, and the `BuiltinSampler` handle must not be null (D-E1) | +| `MGPProgramDesc` | per-stage SPIR-V + reflection archive (§7) | +| `MGPFramebufferState` | 8 color + depth + stencil + the client-resolved read surface; `ContentHash` is both the render-pass memo key and the emission suppressor; `Target` includes `Named = 3`, and the applier stores by framebuffer handle | | `MGPSubData` / `MGPSubRegion` | §6 | -| `MGPDrawInfo` / `MGPDrawRange` | `DrawVbo`;multi-draw 范围与用户索引在变长尾,indirect 的 `DrawCount` 由 client 解析 | +| `MGPDrawInfo` / `MGPDrawRange` | `DrawVbo`; multi-draw ranges and user indices in the variable-length tail, indirect's `DrawCount` resolved by the client | -每条 `kVarTail` 的 `set_*` 带 `ContentHash`,hash 未变就不发(§5.4)。 +Every `kVarTail` `set_*` carries a `ContentHash`; if the hash is unchanged, nothing is sent (§5.4). -### 4.2 split 下的诚实规则 +### 4.2 Honesty rules under split -同一地址空间里 host 指针能解引用、以 host 地址为 `Offset` 的 blobref 能解析、persistent map 返回的地址能直接用;`inproc` 若借这些捷径变绿,`spawn` 无法复现。所以 split 下编解码一律按跨进程规则执行,`inproc` 也不例外(`MG_Remote/Wire/PipeWireCodec.h`): +In one address space a host pointer can be dereferenced, a blobref with a host address as `Offset` can be resolved, and an address returned by persistent map can be used directly; if `inproc` turns green by borrowing these shortcuts, `spawn` cannot reproduce it. So under split, encoding and decoding always follow cross-process rules, `inproc` included (`MG_Remote/Wire/PipeWireCodec.h`): -1. encoder 把 `MGHostSpan::Ptr` 恒写 `nullptr`,字节放进 `SEG_STAGE`,由 `Seg` / `Offset` 指名。 -2. `MGPBlobRef` 要么完整声明(真实 `Seg`、段内 `Offset`、非零 `Size`),要么三个字段全零。`Seg` 或 `Offset` 非零而 `Size == 0` 正是 monolith emitter 的形状(`Offset` 是 host 地址),split 下按损坏拒绝,不能读成"无 blob",否则未改造 emitter 的字节会被静默丢弃。 -3. decoder 对 `Ptr != nullptr`、内容记录的 `Size == 0`、`Size != 0` 而 `Seg == kSegNone`、`Offset + Size` 越过段尾一律报 `ProtocolCorruption`(`CheckBlobIsHonest`、`RequireDeclaredBlob`、`CheckHostSpanIsHonest`)。记录是否带内容由 payload 的其他字段决定,所以"内容记录须有 blob"由 decoder 的逐 op 分支调用 `RequireDeclaredBlob` 检查。 -4. T2 档下 `MGPipeApplyMapPersistent` 在 split 下恒返回 `nullptr`(§12),client 不拿 server 的地址。 -5. `MOBILEGL_IPC_AUDIT=1` 时 server 把已退休记录的 `SEG_STAGE` 字节填成 `0xDD`,apply 之后仍持有指针的实现下一帧会读到 `0xDD`。 +1. The encoder always writes `nullptr` for `MGHostSpan::Ptr`, puts the bytes in `SEG_STAGE`, and names them by `Seg` / `Offset`. +2. `MGPBlobRef` either fully declares itself (real `Seg`, an in-segment `Offset`, nonzero `Size`), or all three fields are zero. `Seg` or `Offset` nonzero with `Size == 0` is exactly the shape of a monolith emitter (`Offset` is a host address); under split it is rejected as corruption and must not be read as "no blob", otherwise the bytes of an unmigrated emitter would be silently dropped. +3. The decoder reports `ProtocolCorruption` for `Ptr != nullptr`, for `Size == 0` on a content record, for `Size != 0` with `Seg == kSegNone`, and for `Offset + Size` running past the end of the segment (`CheckBlobIsHonest`, `RequireDeclaredBlob`, `CheckHostSpanIsHonest`). Whether a record carries content is decided by other fields of the payload, so "a content record must have a blob" is checked by each per-op branch of the decoder calling `RequireDeclaredBlob`. +4. In the T2 tier, `MGPipeApplyMapPersistent` always returns `nullptr` under split (§12); the client does not take the server's address. +5. With `MOBILEGL_IPC_AUDIT=1` the server fills the `SEG_STAGE` bytes of retired records with `0xDD`; an implementation that still holds a pointer after apply reads `0xDD` on the next frame. diff --git a/docs/Disaggregated/design/03-frontend.md b/docs/Disaggregated/design/03-frontend.md index 8e61f104..bda8dd04 100644 --- a/docs/Disaggregated/design/03-frontend.md +++ b/docs/Disaggregated/design/03-frontend.md @@ -1,121 +1,121 @@ -# 前端:state tracker、纹理上传、着色器(原 ARCHITECTURE §5–§7) +# Frontend: state tracker, texture upload, shaders (formerly ARCHITECTURE §5–§7) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design highlights and an index of all sections are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; `ARCHITECTURE.md §N` in code comments resolves by number here. -## 5. 前端 state tracker(`MG_Impl/Pipe/Tracker`) +## 5. Frontend state tracker (`MG_Impl/Pipe/Tracker`) -### 5.1 推送发生在 verb 之前的 validate 时刻,不在 GL setter 里 +### 5.1 Pushing happens at validate time before a verb, not in GL setters -per-setter 推送会把 Blaze3D 每个 batch 的冗余 `glEnable/glDisable` 变成接口调用,严格慢于今天;正确形态是 gallium `st_validate_state`。落地为唯一的 `MGPipeValidateForVerb(MGPipeVerb)`(九个 validate 类,`FillPoints.def`),恰在每次经表调用之前、每个提前返回之后。只有今天就在 GL 调用时刻分发的资源 op(`BufferBackendOps` 的七个 hook)在调用时刻推送。 +Per-setter pushing would turn Blaze3D's redundant `glEnable/glDisable` in every batch into interface calls, strictly slower than today; the correct form is gallium's `st_validate_state`. It lands as the single `MGPipeValidateForVerb(MGPipeVerb)` (nine validate classes, `FillPoints.def`), exactly before every call through the tables and after every early return. Only the resource ops that are already dispatched at GL call time today (the seven hooks of `BufferBackendOps`) push at call time. -### 5.2 dirty 位:值类零新增记账,对象类 5 个聚合世代 +### 5.2 Dirty bits: zero new bookkeeping for value classes, five aggregate generations for object classes -- 值类组(render state、pixel pack、patch、attrib defaults、shader bindings …)直接复用既有版本计数器作快门。 -- 对象类组(vertex buffers、framebuffer、sampler views / samplers / images、const / shader buffers、SO targets)靠 5 个**聚合世代**把快门降成一次 `Uint64` 比较——没有聚合就回答不了"有没有哪张已绑定纹理动了"。 -- 完整性由 `scripts/gen_pipe_dirty_surface.py` 保证(每个 mutator → 必须 bump 的世代,`--check` + `--self-test` 进 CI)。**快门看不见自己的主体**是踩过三次的坑:新增字段必须带"记录字段 → setter → 快门"一行,优先混入已有世代(新计数器会撑大 pull 对象,G1 不允许)。 +- Value-class groups (render state, pixel pack, patch, attrib defaults, shader bindings …) reuse the existing version counters directly as the shutter. +- Object-class groups (vertex buffers, framebuffer, sampler views / samplers / images, const / shader buffers, SO targets) reduce the shutter to a single `Uint64` comparison through five **aggregate generations** — without aggregation there is no way to answer "did any bound texture move". +- Completeness is guaranteed by `scripts/gen_pipe_dirty_surface.py` (every mutator → the generation that must be bumped, `--check` + `--self-test` in CI). **A shutter that cannot see its own subject** is a trap we have hit three times: a new field must come with a "record field → setter → shutter" line, and mixing it into an existing generation is preferred (a new counter would bloat the pull object, which G1 does not allow). -#### 5.2.1 dirty-surface 映射的答案(`DirtySurface.def`) +#### 5.2.1 Answers of the dirty-surface mapping (`DirtySurface.def`) -`DirtySurface.def` 为每个后端可观察的前端 mutator 写明"谁发布这次修改"。漏发布不报错、只会静默渲染陈旧状态,所以清单由 `scripts/gen_pipe_dirty_surface.py` 机械枚举:扫描 `MG_Impl/GLImpl` 与 `MG_State/GLState` 里按 `MUTATOR_PREFIXES` 匹配的 `pGLContext->` 调用和 `MGP_NOTE_MUTATION` 站点(后者带字段名,行写在外层函数上),`--check` 双向核对行集。 +`DirtySurface.def` states, for every frontend mutator observable by the backend, "who publishes this change". A missing publication does not error, it only silently renders stale state, so the list is mechanically enumerated by `scripts/gen_pipe_dirty_surface.py`: it scans `MG_Impl/GLImpl` and `MG_State/GLState` for `pGLContext->` calls matching `MUTATOR_PREFIXES` and for `MGP_NOTE_MUTATION` sites (the latter carry a field name, and the line is written on the enclosing function); `--check` cross-checks the line set in both directions. -答案只列在**每条发生修改的路径**上都触发的发布者(值未变而提前返回不算修改);只在部分路径触发的位若单列,按表构造的快门会欠触发,而欠触发是危险方向。 -- `NEW_*`:`Tracker.h` 的 dirty 位,下一个 verb 发布;`kImmediate`:同一函数体直达后端;`kReverseChannel`:后端写回前端;`kNoBackendRead`:没有后端读点。 -- `kExplicitDestroy`:最后一个引用释放时,client 的 `MGPipeEmit*DestroyAndFree` 依次做 wire 删除(该类有删除行时)、后端通知、释放 slot;`kUnpublishedDestroy`:program pipeline 与 shader 没有 wire 句柄,无从删除。 -- `kPulledEveryVerb`:没有位移动,字段在其 verb 类的 may-read 表里,残余填充每个 verb 都拷贝;`kPulledPartialShutter|NEW_*`:同样靠拉取兜底,所附的位只在部分修改路径上触发。 +The answers list only publishers that fire on **every path that makes a modification** (an early return with an unchanged value does not count as a modification); a bit that fires only on some paths, if listed separately, would make the table-constructed shutter under-trigger, and under-triggering is the dangerous direction. +- `NEW_*`: a dirty bit in `Tracker.h`, published at the next verb; `kImmediate`: straight to the backend from the same function body; `kReverseChannel`: the backend writes back to the frontend; `kNoBackendRead`: there is no backend read site. +- `kExplicitDestroy`: when the last reference is released, the client's `MGPipeEmit*DestroyAndFree` in turn does the wire delete (when the class has a delete line), the backend notification, and frees the slot; `kUnpublishedDestroy`: program pipelines and shaders have no wire handle, so there is nothing to delete. +- `kPulledEveryVerb`: no bit movement; the field is in the may-read table of its verb class, and the residual fill copies it at every verb; `kPulledPartialShutter|NEW_*`: likewise backed by the pull, with the attached bit firing only on some modification paths. -位答案由脚本推导:RenderState 族与 `RenderState.cpp` 双向比对(`BumpVersions()` 动两个计数器,裸 `++m_version` 只动 `NEW_RENDER_STATE`);其余位把快门读的成员 / 字段与 mutator 传递写入的成员 / 字段求交,只能查出"该位的快门在任何路径上都不动"这一种错答,证明不了每条路径都动。写入根定位不了的函数被污染,依赖它的答案为 UNDECIDED,须列入 `MGP_DIRTY_SURFACE_UNDECIDED_LIST`,列了却已可判定同样报红。散文答案不经推导(`kPulledPartialShutter` 所附的位除外);扫描器按文本匹配函数体,lambda 里的 mutator 记到外层函数上,经 helper 发布的修改读作延迟发布,语义证明仍是 `MOBILEGL_PIPE_VERIFY`。 +Bit answers are derived by the script: the RenderState family is compared both ways with `RenderState.cpp` (`BumpVersions()` moves two counters, a bare `++m_version` moves only `NEW_RENDER_STATE`); for the remaining bits, the members / fields the shutter reads are intersected with those the mutator transitively writes, which can only detect the one wrong answer "this bit's shutter never moves on any path", and cannot prove that every path moves. Functions whose write root cannot be located are tainted, and answers that depend on them are UNDECIDED and must be listed in `MGP_DIRTY_SURFACE_UNDECIDED_LIST`; listing one that is already decidable also turns red. Prose answers are not derived (except the bits attached to `kPulledPartialShutter`); the scanner matches function bodies by text, mutators inside lambdas are attributed to the enclosing function, and a change published through a helper is read as a deferred publication; the semantic proof is still `MOBILEGL_PIPE_VERIFY`. -#### 5.2.2 记录字段 → setter → 快门对照表 +#### 5.2.2 Record field → setter → shutter table -由 `Tracker.h` 的 dirty 位触发的每条记录,其每个字段只能经由会推动该位快门输入的 setter 改变,否则必须在 setter 处无条件发射(`resource_*` 族、`set_texture_params`)。`DirtySurface.def` 只把 mutator 映射到位,看不出派生字段依赖另一族的 mutator,所以下表手工维护;记录新增字段时在此加一行。 +Every field of a record triggered by a dirty bit in `Tracker.h` may only change through a setter that moves that bit's shutter input; otherwise it must be emitted unconditionally at the setter (the `resource_*` family, `set_texture_params`). `DirtySurface.def` only maps mutators to bits and cannot see that a derived field depends on a mutator of another family, so the table below is maintained by hand; when a record gains a field, add a row here. -| 位 | 记录与字段 | 改变字段的 setter | 快门输入 | +| Bit | Record and fields | Setters that change the fields | Shutter inputs | |---|---|---|---| -| 6 | `create/bind_shader_state`、`set_draw/dispatch_program`:Cso、StageMask、GlobalUboSize、artefact blob ref、两个已绑定句柄 | `glUseProgram`、`glLinkProgram`、`glBindProgramPipeline`、`glUseProgramStages` | lifetime id × link version;pipeline 下为 `stageLinks`(pipeline 名 × 各 stage 的 lifetime id 与 link version) | -| 7 | program 绑定:image unit、block binding、uniform 写集合 | opaque uniform 上的 `glUniform1i`、`glUniformBlockBinding`、`glShaderStorageBlockBinding`、任意 `glUniform*` | 四个 per-program 计数器;pipeline 下再混入 `stageLinks` | -| 8 | `set_global_constants`:ShaderCso、Version、默认 uniform 块镜像 | 默认块上的 `glUniform*`、`glUseProgram` | lifetime id × UBO content version;pipeline 下为 `stageState` | -| 11 | `set_framebuffer_state`:Fbo、Color[8]/Depth/Stencil/ReadSurface(Res、Kind、InternalFormat、TextureTarget、Layered、Level、Layer、UploadTarget)、DrawBuffers[8]、Width/Height/Layers/Samples/FixedSampleLocations、IsDefault、Complete、Target | `glFramebufferTexture*`、`glFramebufferRenderbuffer`、`glDrawBuffer(s)`、`glReadBuffer`、`glFramebufferParameteri`、`glBindFramebuffer`;已挂接纹理或 renderbuffer 的存储重定义(格式、纹理目标、尺寸、采样数、完备性在发射时内联,所以 `PipePublishDescriptor` bump attachment 聚合) | attachment 聚合 × draw / read 绑定槽版本 | -| 12 | `set_sampler_views`:每单元 {View, Texture} | `glBindTexture`、`glActiveTexture`、纹理或 sampler 参数、定义 level 的上传、默认纹理出现;在用 program(`glUseProgram`、relink、sampler uniform 的 `glUniform1i`) | content × params × bind generation × `opaqueUnits` | -| 13 | `bind_sampler_states`:每单元 sampler CSO 句柄 | `glBindSampler`、`glDeleteSamplers`、`glSamplerParameter*`、`glTexParameter*` | params × sampling resolution × bind generation | -| 14 | `set_shader_images`:program image-unit 窗口内每单元 {Res, InternalFormat, Layer, Level, Layered, Access} | `glBindImageTexture`、纹理 content / params、image uniform 的 `glUniform1i`;在用 program(`glUseProgram`、relink) | content × params × bind generation × `programImages` | +| 6 | `create/bind_shader_state`, `set_draw/dispatch_program`: Cso, StageMask, GlobalUboSize, artifact blob ref, the two bound handles | `glUseProgram`, `glLinkProgram`, `glBindProgramPipeline`, `glUseProgramStages` | lifetime id × link version; under a pipeline, `stageLinks` (pipeline name × each stage's lifetime id and link version) | +| 7 | program bindings: image units, block bindings, uniform write set | `glUniform1i` on opaque uniforms, `glUniformBlockBinding`, `glShaderStorageBlockBinding`, any `glUniform*` | the four per-program counters; under a pipeline, `stageLinks` is mixed in as well | +| 8 | `set_global_constants`: ShaderCso, Version, default uniform block mirror | `glUniform*` on the default block, `glUseProgram` | lifetime id × UBO content version; under a pipeline, `stageState` | +| 11 | `set_framebuffer_state`: Fbo, Color[8]/Depth/Stencil/ReadSurface (Res, Kind, InternalFormat, TextureTarget, Layered, Level, Layer, UploadTarget), DrawBuffers[8], Width/Height/Layers/Samples/FixedSampleLocations, IsDefault, Complete, Target | `glFramebufferTexture*`, `glFramebufferRenderbuffer`, `glDrawBuffer(s)`, `glReadBuffer`, `glFramebufferParameteri`, `glBindFramebuffer`; storage redefinition of an attached texture or renderbuffer (format, texture target, size, sample count, completeness are inlined at emission, so `PipePublishDescriptor` bumps the attachment aggregate) | attachment aggregate × draw / read binding slot version | +| 12 | `set_sampler_views`: per unit {View, Texture} | `glBindTexture`, `glActiveTexture`, texture or sampler parameters, uploads defining a level, appearance of the default texture; the program in use (`glUseProgram`, relink, `glUniform1i` of a sampler uniform) | content × params × bind generation × `opaqueUnits` | +| 13 | `bind_sampler_states`: per unit, the sampler CSO handle | `glBindSampler`, `glDeleteSamplers`, `glSamplerParameter*`, `glTexParameter*` | params × sampling resolution × bind generation | +| 14 | `set_shader_images`: per unit within the program's image-unit window, {Res, InternalFormat, Layer, Level, Layered, Access} | `glBindImageTexture`, texture content / params, `glUniform1i` of an image uniform; the program in use (`glUseProgram`, relink) | content × params × bind generation × `programImages` | -位 11–14 还在 share group 的孪生聚合时钟变化时触发(setter 经兄弟 context 调用);最大触及纹理单元变化时 12、13 也触发。 +Bits 11–14 also fire when the share group's twin aggregate clock changes (the setter is invoked through a sibling context); when the maximum touched texture unit changes, 12 and 13 also fire. -### 5.3 渲染状态:整块 blob 过线,身份只取 pipeline 子集(D-B1) +### 5.3 Render state: one whole blob crosses the wire, identity takes only the pipeline subset (D-B1) ``` -create_render_state(cso, pipelineSubsetChunks) // 只带 pipeline 子集 -bind_render_state(cso, version, pipelineVersion) // 稳态 12 B -set_dynamic_state(dynamicChunks, version) // 只带变化的动态 chunk +create_render_state(cso, pipelineSubsetChunks) // pipeline subset only +bind_render_state(cso, version, pipelineVersion) // 12 B in steady state +set_dynamic_state(dynamicChunks, version) // only the changed dynamic chunks ``` -- `RenderStateParameters`(1168 B)整块过线:Espryt 做三段 memcmp,字段顺序承重;拆成多个 CSO 要手工维护 ~150 字段划分且无绊线。 -- 身份只取 pipeline 子集,否则 `glViewport` / `glScissor` 每次都铸新 CSO、冲掉 server 的 pipeline memo。划分只写在一处:`MGPipeRenderStateSpans` 的 chunk 表(7 pipeline chunk 396 B + 8 dynamic chunk 772 B,`static_assert` 完整性),G7 断言"子集 hash 变 ⟺ `m_pipelineStateVersion` 变"。 -- Espryt 的 `SyncRenderState` 一行不动;Magma 的 pipeline memo 键是 `cso.slot`。 +- `RenderStateParameters` (1168 B) crosses as one whole block: Espryt does a three-segment memcmp, and field order is load-bearing; splitting it into several CSOs would require hand-maintaining a ~150-field partition with no tripwire. +- Identity takes only the pipeline subset, otherwise `glViewport` / `glScissor` would mint a new CSO every time and flush the server's pipeline memo. The partition is written in one place only: the chunk table in `MGPipeRenderStateSpans` (7 pipeline chunks 396 B + 8 dynamic chunks 772 B, `static_assert` completeness), and G7 asserts "the subset hash changes ⟺ `m_pipelineStateVersion` changes". +- Espryt's `SyncRenderState` is untouched; Magma's pipeline memo key is `cso.slot`. -### 5.4 验证不变式、合并与抑制器 +### 5.4 Validation invariants, merging and suppressors -规范(D-B3):**一条 verb 的全部 `set_*` / `bind_*` 在该 verb 之前完成;server 在 verb 处从已推送状态惰性特化 shader 与 pipeline。**除"资源 create 先于对它的 bind"外,`set_*` 之间无顺序要求。合并:整块优于逐字段;高水位直接是 `count` 实参;只发 program 解析过的集合;**集合 hash 抑制器**在 client 侧去抖(原先在后端的 ~175 行)。 +The rule (D-B3): **all `set_*` / `bind_*` of a verb complete before that verb; the server lazily specializes shaders and pipelines at the verb from the pushed state.** Apart from "a resource is created before it is bound", there is no ordering requirement among `set_*`. Merging: whole blocks beat per-field; the high-water mark is directly the `count` argument; only the sets the program resolved are sent; the **set hash suppressor** debounces on the client side (previously ~175 lines in the backend). -### 5.5 sampler view 在 client 侧解析 +### 5.5 Sampler views are resolved on the client -shader 看见哪个纹理取决于 sampler uniform 类型、mipmap 完备性与未定义默认纹理;解析留在 client(带 memo),gallium "每槽一个 view" 就是解析后的形态。两处后端特定后处理留在 server:Espryt 的 raw-depth-fetch sampler 替换、Magma 的 feedback-loop 检测。 +Which texture a shader sees depends on the sampler uniform type, mipmap completeness and the undefined default texture; resolution stays on the client (with a memo), and gallium's "one view per slot" is the resolved form. Two backend-specific post-processing steps stay on the server: Espryt's raw-depth-fetch sampler substitution and Magma's feedback-loop detection. -### 5.6 生命周期、共享组、composite program +### 5.6 Lifetime, share groups, composite programs -- `resource_create` 在前端对象构造时发,存储由 `resource_respecify` 惰性定义,`resource_destroy` 在析构时发;死亡转发给每个 emitter(只释放 slot 曾导致 UAF)。view 先于存储属主销毁、FBO attachment 钉住纹理、buffer texture 钉住 buffer。 -- program pipeline 合成体(`CompositeResolver`)完全在前端合成、推一个句柄;释放恰好一次(resolver 换掉或 `~ProgramObject`,D-H7);记忆按 `(ContextId, 管线 GL 名)` 键控。 +- `resource_create` is sent when the frontend object is constructed, storage is lazily defined by `resource_respecify`, and `resource_destroy` is sent at destruction; the death is forwarded to every emitter (freeing only the slot previously caused a UAF). A view is destroyed before its storage owner, an FBO attachment pins its texture, and a buffer texture pins its buffer. +- The program pipeline composite (`CompositeResolver`) is fully composed on the frontend and pushes a single handle; it is released exactly once (the resolver swaps it out, or `~ProgramObject`, D-H7); the memo is keyed by `(ContextId, pipeline GL name)`. -#### 5.6.1 program pipeline 合成体的句柄、释放与记忆键 +#### 5.6.1 Handle, release and memo key of the program pipeline composite -- 合成体由 `GLContext::GetProgramForDraw()` 在前端合成、缓存在各自的 `ProgramPipelineObject` 里;program 发射器按合成体自己的 lifetime id 从 `ShaderCso` 保留高段(§2.1)给它一个句柄,照普通 program 发 `create_shader_state`,server 不知道它是合成体。`MGPipeSlotAllocator::Allocate` 拒绝该段,`AllocateComposite` 是唯一入口;用保留段而不用句柄 flag,是因为 flag 要被两侧每个 `ShaderCso` 消费者携带和屏蔽,而保留段让"普通 program 拿不到合成体 slot"由分配器保证。 -- slot 有两条释放路径:签名变化时 `MGPipeCompositeResolver::Observe` 释放旧合成体,以及合成体自己的 `~ProgramObject`。两条都走 `MGPipeEmitShaderCsoDestroyAndFree`,后到的一条是空操作(`MGPipeSlotAllocator::Free` 拒绝不在该世代 live 的 slot,也不推进世代)。只靠析构不够:前端一旦多持一份引用,签名变化时析构就不会先到。 -- 签名取 `ComputeDrawProgramSignature()`(每个图形 stage 的 lifetime id 与 link version),不含 `GetBackendStateVersion()`:后者在 sampler uniform 的 `glUniform1i` 时也会变,会让合成体每次 draw 都重新编译。`Tracker.h` 的位 6 快门读同一组值。 -- 记忆键是 `(GLContext::GetTextureContextId(), 管线 GL 名)`:resolver 是进程单例,而 pipeline 名按 context 分配,只按名键控会在 make-current 后命中另一 context 的同名项、释放一个仍活着的合成体,每次切换都重建 program;context 地址也不行,销毁重建的 context 会落在旧地址上,而这个 id 永不复用。 -- context 销毁时其合成体经 `~ProgramObject` 释放,残留项再也查不到;make-current 时的 `Reset()` 丢弃它们而不释放,表长因此只受合成体 slot 仍 live 的项限制。 +- The composite is composed on the frontend by `GLContext::GetProgramForDraw()` and cached in its own `ProgramPipelineObject`; the program emitter reserves the high segment of `ShaderCso` by the composite's own lifetime id (§2.1) and gives it a handle, sending `create_shader_state` like an ordinary program, and the server does not know it is a composite. `MGPipeSlotAllocator::Allocate` rejects that segment and `AllocateComposite` is the only entry; the reserved segment is used instead of a handle flag because a flag would have to be carried and masked by every `ShaderCso` consumer on both sides, whereas the reserved segment makes "an ordinary program cannot get a composite slot" guaranteed by the allocator. +- A slot has two release paths: `MGPipeCompositeResolver::Observe` releases the old composite when the signature changes, and the composite's own `~ProgramObject`. Both go through `MGPipeEmitShaderCsoDestroyAndFree`, and the later one is a no-op (`MGPipeSlotAllocator::Free` rejects a slot not live in that generation and does not advance the generation either). Relying on the destructor alone is not enough: once the frontend holds an extra reference, the destructor will not come first when the signature changes. +- The signature is `ComputeDrawProgramSignature()` (each graphics stage's lifetime id and link version), excluding `GetBackendStateVersion()`: the latter also changes on `glUniform1i` of a sampler uniform, which would make the composite recompile on every draw. Bit 6's shutter in `Tracker.h` reads the same set of values. +- The memo key is `(GLContext::GetTextureContextId(), pipeline GL name)`: the resolver is a process singleton, while pipeline names are allocated per context; keying by name alone would hit the same-named entry of another context after make-current and release a composite that is still alive, rebuilding the program on every switch; the context address is also wrong, because a destroyed and recreated context can land at the old address, whereas this id is never reused. +- When a context is destroyed, its composite is released through `~ProgramObject`, and leftover entries can never be found again; `Reset()` at make-current discards them without releasing, so the table length is bounded only by the entries whose composite slots are still live. -### 5.7 emulation 的归属 +### 5.7 Ownership of emulation -规则:**驱动表达不了的变换在 tracker 里 lowering,硬件 / 驱动强加的变换在 driver 里 lowering。** +Rule: **transformations the driver cannot express are lowered in the tracker; transformations forced by the hardware / driver are lowered in the driver.** -| 归 client(读前端字节的纯 CPU 变换) | 归 server | +| Falls to the client (pure CPU transformations that read frontend bytes) | Falls to the server | |---|---| -| client 顶点 / 索引数组(字节过线,永不是指针)、最大索引扫描、`*IndirectCount` 计数解析、CopyImage shadow 镜像、XFB CPU 图元计数、压缩纹理 / unpack 规整 | primitive-restart 重写、multi-draw 分档与展平(从索引宿主镜像读,§10.3)、viewport-array 回放、fp64 顶点窄化、image-bindable 存储加宽、生成 mipmap(client 分配 level 存储) | +| client vertex / index arrays (bytes cross the wire, never pointers), maximum index scan, `*IndirectCount` count resolution, CopyImage shadow mirror, XFB CPU primitive count, compressed texture / unpack normalization | primitive-restart rewriting, multi-draw tiering and flattening (read from the index host mirror, §10.3), viewport-array replay, fp64 vertex narrowing, image-bindable storage widening, mipmap generation (the client allocates level storage) | -**陈旧索引纪律是逐站点表**:client 侧扫描前的 reconcile 必须逐字复现 monolith 的集合(最大索引扫描 = `SyncPersistentMappedRange()` + `SyncGpuWrites()`;`*IndirectCount` 只前者)。 +**Stale index discipline is a per-site table**: the reconcile before a client-side scan must reproduce monolith's set verbatim (maximum index scan = `SyncPersistentMappedRange()` + `SyncGpuWrites()`; `*IndirectCount` only the former). -## 6. 纹理 subdata 与 dirty 归属 +## 6. Texture subdata and dirty ownership -- 纹理上传由 Espryt 在 sync 时刻按**累积**区域做(Mali 按作业数计价,~100 个 rect 对一个 union box 实测 +6 ms/帧),逐 `glTexSubImage` 发记录会复现这个悬崖。 -- 因此 client 在自己的 rect 模型里累积,在下一个 validate / flush 点发**一条** `ResourceSubData`,同时携带 union box 与 region 列表,**由 server 选上传形状**(决策留在付 GPU 代价的一侧)。步长显式携带,不再靠指针比较。 -- **dirty 归属反转**:client 维护发射游标、发射后清自己的标志;清 dirty 要等 applier 的 acceptance(被拒的 level 留在脏表里);server 自己的重新变脏是 server 的事。 -- `TextureUploadShapeScenario` 把上传形状录成金标(P3b/P4b D2 起是门;Mali 帧时增量无设备,按 Adreno 记录)。 +- Texture uploads are done by Espryt at sync time over the **accumulated** region (Mali prices by job count; ~100 rects against one union box measured +6 ms/frame), so sending a record per `glTexSubImage` would reproduce this cliff. +- So the client accumulates in its own rect model and sends **one** `ResourceSubData` at the next validate / flush point, carrying both the union box and the region list, and **the server picks the upload shape** (the decision stays on the side that pays the GPU cost). The stride is carried explicitly, no longer relying on pointer comparison. +- **Dirty ownership is reversed**: the client maintains the emission cursor and clears its own flags after emission; clearing dirty waits for the applier's acceptance (a rejected level stays in the dirty table); the server's own re-dirtying is the server's business. +- `TextureUploadShapeScenario` records the upload shape as golden (a gate since P3b/P4b D2; Mali frame-time deltas have no device here, recorded on Adreno). -### 6.1 server 侧待上传集合 +### 6.1 Server-side pending upload set -- client 在 applier 接受某 level 的 `ResourceSubData` 时就清掉自己的 dirty 标志;后端的上传循环有提前返回的臂(Espryt:纹理不完备、multisample 目标只刷新),所以已接受的形状由 applier 按 `(uploadTarget, level)` 累积在 `MGPipeResourceRecord::PendingUploads`,只在后端真正上传处消费并清除,任意次 bail 都不丢纹素。 -- 累积沿用 client 的 rect 模型:union box 取并、rect 列表拼接;任一侧只有 box,或列表将超过 `kMGPipeMaxPendingUploadRegions`,该项退化为只有 box(仍覆盖全部纹素,只多传空隙)。 -- respecify 只丢弃它替换掉的那份存储上的待上传(盒子在那份存储的坐标系里,跨缩小保留会越界上传): - - level 为空 = 整资源重定义(`glBufferData` / `glBufferStorage`、`glTexStorage*`、纹理视图),全部清空; - - 具名 level = 一次 `glTexImage*D`,只丢该 `(uploadTarget, level)`,与描述符是否变化无关。整体清空会丢掉别的 level 已被接受、尚未上传的纹素:`glTexImage2D(0)` → draw(纹理不完备,后端 bail)→ `glTexImage2D(1)`; - - 只换元数据(`RespecifyRedefinesNoStorage`:sticky 的 `BindMask` / `ImageBindableHint` 变化时重发的描述符)不丢任何项。 -- buffer 没有待上传项,也永远不算只换元数据。 +- The client clears its dirty flag for a level as soon as the applier accepts that level's `ResourceSubData`; the backend's upload loop has early-return arms (Espryt: incomplete texture, multisample target only refreshes), so accepted shapes are accumulated by the applier per `(uploadTarget, level)` in `MGPipeResourceRecord::PendingUploads`, consumed and cleared only where the backend actually uploads, and no number of bails loses texels. +- Accumulation reuses the client's rect model: the union box is taken as a union, rect lists are concatenated; if either side has only a box, or the list would exceed `kMGPipeMaxPendingUploadRegions`, that entry degrades to a box-only entry (still covering every texel, just transferring extra gaps). +- respecify discards only the pending uploads on the storage it replaces (the boxes are in that storage's coordinate system; preserving them across a shrink would upload out of bounds): + - an empty level = a whole-resource redefinition (`glBufferData` / `glBufferStorage`, `glTexStorage*`, texture views), clearing everything; + - a named level = one `glTexImage*D`, dropping only that `(uploadTarget, level)`, regardless of whether the descriptor changed. Clearing everything would lose texels of other levels that were already accepted but not yet uploaded: `glTexImage2D(0)` → draw (texture incomplete, backend bails) → `glTexImage2D(1)`; + - a metadata-only change (`RespecifyRedefinesNoStorage`: the descriptor re-sent when the sticky `BindMask` / `ImageBindableHint` changes) drops nothing. +- A buffer has no pending uploads and never counts as metadata-only either. -#### 6.1.1 region 列表是精确脏足迹 +#### 6.1.1 The region list is the exact dirty footprint -纹理 `resource_subdata` 的 region 列表是该 level 自上次变干净以来的**精确脏足迹**:互不相交的盒子,覆盖每个写过的纹素,不多一个(`MGPipeTextureEmitter::EmitOneLevel`)。原因:server 端图像一旦可能含 GPU 写入,超出应用写入范围的上传就会盖掉它们。Magma 总把列表当作要上传的纹素;Espryt 在驱动纹理可能含 GPU 写入时同样如此,否则仍自己在 box 与 rect 之间选上传形状(Mali 作业数照旧由 server 决定)。 -- `RegionCount == 0` 只表示整 level 写;其余写入一律带盒子(只有一个也带),所以 applier 的累积不会因为某一侧「只有 box」而把精确贡献放宽成并集盒。 -- 例外:足迹超过一条记录能带的 `kMGPipeMaxPendingUploadRegions` 个盒子时,退回存储的 rect 列表(只保证覆盖,日志记一次);该列表又被扣下(rect 填满并集盒的 3/4)时,0 是一个**不精确**的部分盒。把「只有 box」读作「client 拥有盒内每个纹素」的读者(`AdoptDriverLevelIntoShadow` 的覆盖盒规则)只在这种情况下不精确。 +The region list of a texture `resource_subdata` is the **exact dirty footprint** of that level since it last became clean: disjoint boxes that cover every written texel and not one more (`MGPipeTextureEmitter::EmitOneLevel`). Reason: once a server-side image may contain GPU writes, an upload beyond the application's write range would overwrite them. Magma always treats the list as the texels to upload; Espryt does the same when the driver texture may contain GPU writes, and otherwise still chooses the upload shape itself between the box and the rects (the Mali job count is still decided by the server). +- `RegionCount == 0` only means a whole-level write; every other write carries boxes (even a single one), so the applier's accumulation never relaxes an exact contribution into a union box because one side is "box only". +- Exception: when the footprint exceeds the `kMGPipeMaxPendingUploadRegions` boxes one record can carry, it falls back to the storage's rect list (coverage only, logged once); when that list is in turn withheld (the rects fill 3/4 of the union box), 0 is an **inexact** partial box. Readers that read "box only" as "the client owns every texel in the box" (the coverage-box rule of `AdoptDriverLevelIntoShadow`) are inexact only in this case. -#### 6.1.2 纹理视图的上传记在存储属主上 +#### 6.1.2 Texture view uploads are recorded on the storage owner -`glTextureView` 与源纹理共用纹素,所以 client 把经视图或经属主名字做的每次上传都记在**存储属主**上:`TextureObjectView` 把 dirty 标记换算成属主坐标(`ToOwnerLevel` / `ToOwnerUploadTarget` / `ToOwnerRegionOffset`)转给属主,`TextureEmit.h` 的排空列表按(存储属主, upload target, level)键控,每条纹理 `resource_subdata` 都指向属主句柄;applier 因此只推进属主记录的 `Serial` 与 `PendingUploads`。 -- Espryt 的逐纹理 clean 门 `BackendTextureObject::IsDrawSyncCleanByRecord` 对两个存储条款读 `Desc.ViewOf` 指向的属主记录(`PipeTextureStorageRecordForRecord`),三个参数条款仍读视图自己的记录:视图有自己的纹理参数与内建 sampler。这与前端 `TextureObjectView::GetContentVersion()` 转发给属主是同一条规则。 -- 若存储条款读视图自己的记录,视图第一次被采样之后,经属主名字的上传在视图上永不可见。门是 `TextureViewAliasScenario.TheOwnerUploadDrainRunsAgainAfterADrawBoundary`,monolith 与三个传输臂都跑。 +`glTextureView` shares texels with the source texture, so the client records every upload made through a view or through the owner's name on the **storage owner**: `TextureObjectView` converts the dirty mark into owner coordinates (`ToOwnerLevel` / `ToOwnerUploadTarget` / `ToOwnerRegionOffset`) and forwards it to the owner, the drain list in `TextureEmit.h` is keyed by (storage owner, upload target, level), and every texture `resource_subdata` points at the owner handle; the applier therefore advances only the owner record's `Serial` and `PendingUploads`. +- Espryt's per-texture clean gate `BackendTextureObject::IsDrawSyncCleanByRecord` reads the owner record pointed to by `Desc.ViewOf` (`PipeTextureStorageRecordForRecord`) for the two storage clauses, while the three parameter clauses still read the view's own record: a view has its own texture parameters and built-in sampler. This is the same rule as the frontend's `TextureObjectView::GetContentVersion()` forwarding to the owner. +- If the storage clauses read the view's own record, uploads through the owner's name would never become visible on the view after it is first sampled. The gate is `TextureViewAliasScenario.TheOwnerUploadDrainRunsAgainAfterADrawBoundary`, run under monolith and all three transport arms. -## 7. Shader state = SPIR-V + 反射归档 +## 7. Shader state = SPIR-V + reflection archive -- `CreateShaderState` 过线的是逐 stage SPIR-V + 反射归档,**不是源码**:glslang 全在 client、SPIRV-Cross 全在 server,文件级切割;server 侧无编译池。归档序列化器 `ProgramArtifactsCodec`,monolith 只在 verify 构建里调它(D-H3)。 -- server 在 verb 时刻从已推送状态**惰性特化**(D-B2:draw FBO clamp mask、fragColor 广播数、storage-block 绑定签名、image 格式、patch 参数等)——正是两个后端原来的做法。 -- link / compile 失败不需要同步返回:`GL_LINK_STATUS` 由 client 从 `ProgramObject` 回答,后端失败以 server 日志的 ≥ERROR 行(控制面 `LogLine`,无损,`MG_Remote/Transport/LogForward.h`)呈现。 -- 内部 shader(颜色 blit、深度 mip、multisample resolve)烘焙成签进树的 SPIR-V(`Wire*Spirv.h`),新鲜度门 `MOBILEGL_BAKED_INTERNAL_SHADERS`(`MG_Test/SelfTest/BakedInternalShadersTest.cpp`)重跑树内 glslang 逐字节比对(P7)。 +- `CreateShaderState` sends per-stage SPIR-V + a reflection archive across the wire, **not source**: glslang entirely on the client, SPIRV-Cross entirely on the server, a file-level split; no compile pool on the server. The archive serializer is `ProgramArtifactsCodec`, and monolith calls it only in verify builds (D-H3). +- The server **lazily specializes** at the verb from the pushed state (D-B2: draw FBO clamp mask, fragColor broadcast count, storage-block binding signature, image formats, patch parameters, etc.) — exactly what the two backends did before. +- link / compile failure needs no synchronous return: `GL_LINK_STATUS` is answered by the client from the `ProgramObject`, and backend failures surface as ≥ERROR lines in the server log (control-plane `LogLine`, lossless, `MG_Remote/Transport/LogForward.h`). +- Internal shaders (color blit, depth mip, multisample resolve) are baked into SPIR-V signed into the tree (`Wire*Spirv.h`), and the freshness gate `MOBILEGL_BAKED_INTERNAL_SHADERS` (`MG_Test/SelfTest/BakedInternalShadersTest.cpp`) reruns in-tree glslang and compares byte for byte (P7). diff --git a/docs/Disaggregated/design/04-reverse-channel.md b/docs/Disaggregated/design/04-reverse-channel.md index c53be181..6127abc4 100644 --- a/docs/Disaggregated/design/04-reverse-channel.md +++ b/docs/Disaggregated/design/04-reverse-channel.md @@ -1,62 +1,62 @@ -# 反向通道(原 ARCHITECTURE §8) +# Reverse Channel (formerly ARCHITECTURE §8) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design highlights and an index of all sections are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; `ARCHITECTURE.md §N` in code comments resolves by number here. -## 8. 反向通道 +## 8. Reverse channel -### 8.1 `MGPipeCallbacks`(`MG_Pipe/MGPipeCallbacks.h`) +### 8.1 `MGPipeCallbacks` (`MG_Pipe/MGPipeCallbacks.h`) -七个具名回调,取代后端直接 poke 前端对象的 95 个调用点(具名化是有意偏离 D8)。monolith 下直调,split 下是 `SEG_EVENT` 上的记录。 +Seven named callbacks replace the 95 call sites where the backend directly pokes frontend objects (the naming is a deliberate deviation D8). Under monolith they are direct calls; under split they are records on `SEG_EVENT`. -| 回调 | 作用 | +| Callback | Role | |---|---| -| `OnGlError` | 延迟的 GL 错误;**必须对命令流有序** | -| `OnGpuWritten` | GPU 写过的 buffer 范围(收窄 client 保守自建的 pending 集) | -| `OnBufferWriteback` | PBO 回读、XFB 捕获结果;必须与 epoch bump 有序 | -| `OnTextureWriteback` | CPU 回退生成 mip 的纹素 | -| `OnMipLevelsGenerated` | 只带形状 | -| `OnSurfaceChanged` | 默认帧缓冲的格式与尺寸(server 拥有显示时 client 靠它得知窗口尺寸) | -| `OnCapsInvalidated` | 取代 `InvalidateCompileEnv` | +| `OnGlError` | deferred GL errors; **must be ordered with respect to the command stream** | +| `OnGpuWritten` | buffer ranges the GPU has written (narrowing the client's conservatively built pending set) | +| `OnBufferWriteback` | PBO readback, XFB capture results; must be ordered with the epoch bump | +| `OnTextureWriteback` | texels of CPU-fallback generated mips | +| `OnMipLevelsGenerated` | shape only | +| `OnSurfaceChanged` | format and size of the default framebuffer (when the server owns the display, this is how the client learns the window size) | +| `OnCapsInvalidated` | replaces `InvalidateCompileEnv` | -`OnLog` 已删除(P9 W3;与 W2 删除的 `OnTexturePullRequest` 合计,回调 9 → 7):零生产者、零消费者、无 `EventKind`。server 日志走控制面 `LogLine`(带 `level`),由 `MG_Remote/Transport/LogForward.h` 的队列 + 发送线程转发:≤WARN 有损(队列满即丢、计数、流内 `LogForward{Dropped}` 标出缺口),≥ERROR 无损 + 限速(超速排队延迟;超出错误字节上限时合并成一条 `LogForward{Coalesced}`),FATAL 有界等待写出;日志线程永不等 socket。 +`OnLog` has been removed (P9 W3; together with `OnTexturePullRequest` removed in W2, callbacks 9 → 7): zero producers, zero consumers, no `EventKind`. Server logs go through the control-plane `LogLine` (with `level`), forwarded by the queue + sending thread in `MG_Remote/Transport/LogForward.h`: ≤WARN is lossy (dropped when the queue is full, counted, the gap marked in-stream by `LogForward{Dropped}`), ≥ERROR is lossless + rate-limited (over-rate lines queue with delay; when the error byte cap is exceeded they are merged into one `LogForward{Coalesced}`), FATAL waits with a bound to be written out; the logging thread never waits on the socket. -后端凭空造的前端对象(Magma 占位纹理、swapchain 默认 FB 占位)改为 server 原生;pull 构建里的 `m_backend` 类成员真删会动 `sizeof`(G1),随 P13 退役(D-K)。 +Frontend objects invented out of thin air by the backend (Magma placeholder textures, the swapchain default FB placeholder) become server-native; truly deleting the `m_backend`-style members in pull builds would change `sizeof` (G1), so they retire with P13 (D-K). -### 8.2 有序性是正确性要求 +### 8.2 Ordering is a correctness requirement -每次 writeback 之后的 epoch bump 必须在任何后续读该 handle 的命令之前被 server 应用。**反向通道需要与正向通道相同的有序保证。** +The epoch bump after each writeback must be applied by the server before any later command that reads that handle. **The reverse channel needs the same ordering guarantee as the forward channel.** -### 8.3 错误、ack 与日志 +### 8.3 Errors, acks and logs -- **唯一允许同步 ack 的入口是 `glBufferStorage`**:`ResourceRespecify` 的 `kNeedsAck` 由逐记录谓词收窄到"不可变 **buffer**"(D-A2),纹理 OOM 在 monolith 里本来就推迟到 sync 时刻。respecify 带逐 level 作用域与"只换元数据"的形式,不误丢已接受的待上传。 -- 其余错误一律晚到,走有序的 `OnGlError`。 +- **The only entry allowed to ack synchronously is `glBufferStorage`**: `ResourceRespecify`'s `kNeedsAck` is narrowed by a per-record predicate to the "immutable **buffer**" (D-A2); texture OOM was already deferred to sync time under monolith. respecify carries per-level scope and a "metadata-only" form, and does not mistakenly drop accepted pending uploads. +- All other errors are late, going through the ordered `OnGlError`. -#### 8.3.1 server 日志的转发队列 +#### 8.3.1 The server log forwarding queue -`MG_Remote/Transport/LogForward.h` 的 `LogForwardChannel`:`Offer` 只在通道互斥锁下拷贝一行入队,唯一的发送线程按入队顺序写帧,写 socket 时不持锁,所以 FATAL 以下的行花在转发上的只是一次加锁加一次拷贝(`LogForwardCounters::maxOfferNs`),与对端是否在读无关。server 自己的日志文件在转发之前写(`Log.cpp`),总有全部行。 -- DEBUG / INFO / WARN 有损:使有损字节超过 `lossyQueueBytes` 的行丢弃并计数;缺口闭合时(下一条放得下的 ≤WARN 行、`LogFlush` ack 或 `Close`)通道自己插一条 WARN `LogForward{Dropped}`,写明条数、字节与起始时间。 -- ERROR 无损、限速:令牌桶(`errorBurstLines` 起步、`errorLinesPerSecond` 补充),超速的行按序排队延迟、不丢;排队的错误字节超过 `errorQueueBytes`(有损上限的 8 倍)时不再入队,由排在下一个能入队条目之前的一条 ERROR `LogForward{Coalesced}` 代替。 -- FATAL = ERROR + 等待:最多等 `fatalFlushMs`,直到发送线程写出它及之前的一切;一次等待超时后,在发送线程写出任何东西之前,后续 FATAL 不再等(`MGLOG_F` 也标记可存活的情形,可能连发)。`Log.cpp` 在日志锁外交出 FATAL 行。 -- `LogFlush` ack(`OfferControlFrame`)排在之前提交的每一行之后,`MGPipeSyncPeerLog` 的「ack 到达时之前的行都已在文件里」因此成立;它排队期间发送线程不限速。 -- `Close()` 不再收行,给队列 `closeDrainMs` 不限速发完;发送线程仍卡在写里时调用属主提供的 `unblock`(`ServerMain`:对控制 socket `shutdown(2)`),以便 join 而不是泄漏线程,剩余条目计为 abandoned。 -- 只有 TCP server 形态转发(`ServerMain.cpp`,`MOBILEGL_IPC_LOG_FORWARD`);unix spawn server 与 inproc apply 线程自己写 `.server.log`。 +`LogForwardChannel` in `MG_Remote/Transport/LogForward.h`: `Offer` only copies one line into the queue under the channel mutex, and the single sending thread writes frames in enqueue order, holding no lock while writing the socket, so for lines below FATAL, forwarding costs only one lock plus one copy (`LogForwardCounters::maxOfferNs`), regardless of whether the peer is reading. The server's own log file is written before forwarding (`Log.cpp`), so it always has all lines. +- DEBUG / INFO / WARN are lossy: a line that would push the lossy bytes over `lossyQueueBytes` is dropped and counted; when the gap closes (the next ≤WARN line that fits, a `LogFlush` ack, or `Close`), the channel itself inserts a WARN `LogForward{Dropped}` stating the count, bytes and start time. +- ERROR is lossless and rate-limited: a token bucket (`errorBurstLines` to start, replenished by `errorLinesPerSecond`); over-rate lines queue in order with delay and are not dropped; when queued error bytes exceed `errorQueueBytes` (8 times the lossy cap), further lines are not enqueued, replaced by one ERROR `LogForward{Coalesced}` placed before the next entry that can be enqueued. +- FATAL = ERROR + waiting: wait at most `fatalFlushMs`, until the sending thread has written it and everything before it; after one wait times out, later FATALs do not wait until the sending thread writes anything (`MGLOG_F` also marks survivable cases, which may fire in succession). `Log.cpp` hands off FATAL lines outside the log lock. +- The `LogFlush` ack (`OfferControlFrame`) is ordered after every previously submitted line, so `MGPipeSyncPeerLog`'s "when the ack arrives, all preceding lines are already in the file" holds; while it is queued, the sending thread is not rate-limited. +- `Close()` accepts no more lines and gives the queue `closeDrainMs` to drain without rate limiting; if the sending thread is still stuck in a write, it calls the owner-supplied `unblock` (`ServerMain`: `shutdown(2)` on the control socket) so the thread can be joined rather than leaked, and remaining entries count as abandoned. +- Only the TCP server form forwards (`ServerMain.cpp`, `MOBILEGL_IPC_LOG_FORWARD`); the unix spawn server and the inproc apply thread write `.server.log` themselves. -### 8.4 纹理重铸:字节全在 server 手里,没有拉取(P9 W2 撤销原「唯一的新停顿类」D-B6) +### 8.4 Texture re-mint: all bytes are in the server's hands, no pull (P9 W2 withdraws the original "only new stall class" D-B6) -原设计假设 server 不保留纹素、重铸要把 level 从 client 拉回来。P5c 之后 server 有 `StagedTextureStore`,GPU 写过的层本来就在 GPU 图像里——**两个后端的重铸都不需要 client 的任何字节**: +The original design assumed the server kept no texels and re-minting had to pull levels back from the client. After P5c the server has `StagedTextureStore`, and GPU-written layers are already in the GPU image — **neither backend's re-mint needs any bytes from the client**: -| | split 下重铸的字节来源 | monolith | +| | Source of re-mint bytes under split | monolith | |---|---|---| -| Espryt | `RequireImageBindableStorageByHandle`:驱动上确实存在的层逐层读回旧 GPU 纹理,pending 盒用 store 合并;驱动没有的层(最后一次 sync 之后才定义)不读,store 覆盖就重放 store,否则跳过;驱动拒读而 store 覆盖时退回 store;已 immutable 且无需加宽的原样保留 | 前端臂重放 client 影子 | -| Magma | 重建带 `STORAGE` 的 VkImage,`PreserveTextureContentsOnRecreate` GPU→GPU 拷贝 | 同左 | +| Espryt | `RequireImageBindableStorageByHandle`: layers that really exist on the driver are read back from the old GPU texture one by one, with pending boxes merged using the store; layers the driver does not have (defined only after the last sync) are not read, store coverage replays the store, otherwise they are skipped; when the driver refuses the read while the store covers it, fall back to the store; layers already immutable and needing no widening are kept as they are | the frontend arm replays the client shadow | +| Magma | rebuild the VkImage with `STORAGE`, `PreserveTextureContentsOnRecreate` GPU→GPU copy | same as left | -- 只改读 store 不够:GPU 写过的层 store 里是旧字节或没有字节;语料里 Espryt 的两次重铸(`iris-photon`、`iris-derivative`)都是 store 无字节的渲染目标。 -- 「整格式再生」两臂都只上传 pending 层、不回读也不拉取;「view 源重铸」只剩源需要加宽,走同一条 ByHandle 路径。 -- 删除:`OnTexturePullRequest`(与 W3 删除的 `OnLog` 合计,回调 9 → 7)、`texture-remint-pull` 标记。op 50 `ResourceSubDataComplete` 只追加不删,留作退役行(解码拒收)。`MOBILEGL_PIPE_TEXEL_RETAIN_MB` 已无消费者,但在 pull 构建里,随 P13 删(G1)。 -- `ImageBindableHint` 仍是预防:hint 在第一次 sync 前到达就直接按 image-bindable 分配,省掉一次 server 回读 + 重传。 -- 已知 dev 缺陷(非 P9):monolith Espryt 的前端臂重放 client 影子,覆盖 GPU 写过的纹素。 -- 普查、覆盖矩阵、门与 red-once:见 git 历史。 +- Changing only what the store reads is not enough: GPU-written layers have old bytes or no bytes in the store; in the corpus both Espryt re-mints (`iris-photon`, `iris-derivative`) are render targets with no bytes in the store. +- "Whole-format regeneration" on both arms uploads only the pending layers, with no readback and no pull; "view source re-mint" leaves only the source needing widening and goes through the same ByHandle path. +- Removed: `OnTexturePullRequest` (together with `OnLog` removed in W3, callbacks 9 → 7), the `texture-remint-pull` flag. op 50 `ResourceSubDataComplete` is append-only and kept as a retired line (decoding rejects it). `MOBILEGL_PIPE_TEXEL_RETAIN_MB` has no consumers left, but in pull builds it is deleted with P13 (G1). +- `ImageBindableHint` is still a precaution: if the hint arrives before the first sync, storage is allocated image-bindable directly, saving one server readback + retransfer. +- Known dev defect (not P9): monolith Espryt's frontend arm replays the client shadow, overwriting GPU-written texels. +- Census, coverage matrix, gates and red-once: see the git history. -### 8.5 XFB scatter 留在 server +### 8.5 XFB scatter stays on the server -补丁循环需要"捕获前的字节",而拆分后权威影子归 server(`StagedShadow`),所以 scatter 在 server 原地跑完;回程只有一条 `OnBufferWriteback`,载补好的整段,按 `SEG_EVENT` 容量的四分之一切片(`MGPipeBufferWritebackSliceBytes`),最后一片落地即蕴含之前每一片。孤儿目标(`HasDefinedContent == 0`)零填充后照常散射。`OnXfbScatterReady` 已删除(回调 10 → 9)。落地论证见 git 历史(espryt D1)。 +The patch loop needs "the bytes before capture", and after the split the authoritative shadow belongs to the server (`StagedShadow`), so scatter runs to completion in place on the server; the return trip is a single `OnBufferWriteback` carrying the patched whole range, sliced to a quarter of `SEG_EVENT` capacity (`MGPipeBufferWritebackSliceBytes`), and landing the last slice implies every preceding one. Orphan targets (`HasDefinedContent == 0`) are zero-filled and scattered as usual. `OnXfbScatterReady` has been removed (callbacks 10 → 9). For the landing argument see the git history (espryt D1). diff --git a/docs/Disaggregated/design/05-backend-and-server.md b/docs/Disaggregated/design/05-backend-and-server.md index c051f7ec..b422f752 100644 --- a/docs/Disaggregated/design/05-backend-and-server.md +++ b/docs/Disaggregated/design/05-backend-and-server.md @@ -1,72 +1,72 @@ -# 后端改造与 server 侧(原 ARCHITECTURE §9–§10) +# Backend Changes and the Server Side (formerly ARCHITECTURE §9–§10) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design highlights and an index of all sections are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; `ARCHITECTURE.md §N` in code comments resolves by number here. -## 9. 后端状态机改造 +## 9. Backend state machine changes -### 9.1 原样不动的东西 +### 9.1 Things left untouched -Espryt 的 persistent ring、buffer pool、fallback-repack、scratch FBO、驱动绑定影子、Adreno / Mali workaround、SPIRV-Cross 会话、restart 重写与 multi-draw 分档;Magma 的 `VulkanRenderer` memo、`PipelineFactory`、`ProgramFactory`、`UniformManager`、五个 `Vk*Manager`、`SwapchainObject`、D18 的节点式容器纪律。"输入变了、算法不许动"的那一类由 **G5 字节一致门**把关(`scripts/p3a_untouched_regions.sh` 十一函数、`scripts/p4a_untouched_regions.sh` 17 区),re-pin 必须两份同改。 +Espryt's persistent ring, buffer pool, fallback-repack, scratch FBO, driver binding shadow, Adreno / Mali workarounds, SPIRV-Cross session, restart rewriting and multi-draw tiering; Magma's `VulkanRenderer` memo, `PipelineFactory`, `ProgramFactory`, `UniformManager`, the five `Vk*Manager`s, `SwapchainObject`, and D18's node-style container discipline. The "inputs changed, algorithm must not" category is guarded by the **G5 byte-identity gate** (`scripts/p3a_untouched_regions.sh` eleven functions, `scripts/p4a_untouched_regions.sh` 17 regions), and a re-pin must change both together. -### 9.2 strangler 脚手架:`PipeInputs` + 逐 verb 填充 + poison 世代(P1) +### 9.2 strangler scaffolding: `PipeInputs` + per-verb fill + poison generation (P1) ```cpp -// MG_Backend/MGPipe/PipeInputs.h —— 按 memo 键组织,访问器类型与后端原来读到的完全一致 +// MG_Backend/MGPipe/PipeInputs.h — organized by memo key, with accessor types exactly matching what the backend read before #if MOBILEGL_PIPE_PUSH -#### 9.2.1 server 侧的 verb 戳与读检查 +#### 9.2.1 Server-side verb stamps and read checks -client 的残余填充在自己的 verb 边界给全部字段盖戳,server 读 `PipeInputs` 前必须换成自己的戳:与 client 共用一块时,不清零则每次读都“新鲜”、`rsp` 恒为 0,门形同虚设;两块分开时,没有戳则第一次读就中止。 +The client's residual fill stamps every field at its own verb boundary, and the server must swap in its own stamp before reading `PipeInputs`: when it shares one block with the client, without zeroing every read is "fresh" and `rsp` is always 0, making the gate a no-op; when the blocks are separate, without a stamp the first read aborts. -- 盖戳点:`PipeApplier::StampVerbBoundary` 只在 `MGPipeVerbForWireOp`(`FieldOwnership.def` 的 `MGP_VERB_OP_LIST`)映到 verb 的 op 上调用 `MGPipeServerStampVerbBoundary`:递增 `CurrentVerbSerial`、记下 verb,给该 verb 类可读掩码(`FillPoints.def`)内的 `RECORD_SUPPLIED` / `APPLIER_DERIVED` 字段盖新戳,其余字段戳清零(“从未填充”先于 sticky 判定,所以清零也取消 sticky 豁免)。 -- 非边界记录(如两次 draw 之间的 `set_dynamic_state`)不盖戳,沿用前一边界的序号、掩码与 verb 名,但盖戳标志已在上一条记录后清除,读检查按盖戳之外处理;20 个 draw 入口都盖成 `DrawArrays`,掩码正确,Fatal 里的名字是泛称。 -- 读检查只在 server 盖戳的 verb 内按归属类(§3.1 的 G8)分流:`RECORD_SUPPLIED` / `APPLIER_DERIVED` 读到旧值是 `Fatal{RoleViolation}`,`FATAL` 直接中止,`BARRIER_PULLED`(仅供生成器对照,没有生产行)在该 verb 类内计入 `rsp`,由 `CountBarrierPull` 决定何时改为中止(记录未 barrier、两角色用不同块、strict 下未准入)。盖戳之外一律是普通 poison `Fatal{UnmigratedPipeInput}`。 -- 盖戳标志由 `PipeApplier::LeaveApplier` 在每条记录之后清除;server 进程里没有 client 半边替它清,漏清会让之后的读都按上一个 verb 的掩码判定。 +- Stamp points: `PipeApplier::StampVerbBoundary` calls `MGPipeServerStampVerbBoundary` only on ops that `MGPipeVerbForWireOp` (`MGP_VERB_OP_LIST` in `FieldOwnership.def`) maps to a verb: it increments `CurrentVerbSerial`, records the verb, stamps `RECORD_SUPPLIED` / `APPLIER_DERIVED` fields within that verb class's readable mask (`FillPoints.def`) with the new stamp, and zeroes the stamps of the rest ("never filled" precedes the sticky test, so zeroing also cancels the sticky exemption). +- Non-boundary records (such as `set_dynamic_state` between two draws) are not stamped and carry over the previous boundary's serial, mask and verb name, but the stamped flag has been cleared after the previous record, so the read check treats them as outside a stamp; all 20 draw entry points are stamped as `DrawArrays`, the mask is correct, and the name in the Fatal is generic. +- The read check splits by ownership class (§3.1's G8) only inside a server-stamped verb: reading a stale value in `RECORD_SUPPLIED` / `APPLIER_DERIVED` is `Fatal{RoleViolation}`, `FATAL` aborts outright, and `BARRIER_PULLED` (for generator cross-check only, no production rows) counts into `rsp` within that verb class, with `CountBarrierPull` deciding when to abort instead (record not barriered, two roles using different blocks, not admitted under strict). Outside a stamp everything is the ordinary poison `Fatal{UnmigratedPipeInput}`. +- The stamped flag is cleared by `PipeApplier::LeaveApplier` after each record; the server process has no client half to clear it, and a missed clear makes every later read judged by the previous verb's mask. -#### 9.2.2 run-ahead 下 client 对 `PipeInputs` 的写 +#### 9.2.2 Client writes to `PipeInputs` under run-ahead -run-ahead 下,unbarriered 记录 apply 期间 `PipeInputs` 是 server 角色内存:对这类 verb,client 不填充、不盖戳、不撤 server 的戳,只跑 tracker 与 emitter(`MGPipeValidateForVerb` 的 `fillOwed`)。GL 线程唯一合法的写是 barriered verb 的填充,而且写的那一刻就得成立: +Under run-ahead, while unbarriered records are being applied, `PipeInputs` is server-role memory: for these verbs the client does not fill, does not stamp, and does not withdraw the server's stamp; it only runs the tracker and the emitter (`MGPipeValidateForVerb`'s `fillOwed`). The only legal write by the GL thread is the fill of barriered verbs, and it must hold at the moment of writing: -- 验证点的顺序是填充 → 发射 → park,填充时 apply 线程可能还在执行先前发布的 unbarriered 记录,所以每次写之前 `QuiesceApplierBeforeFill` 先等 applier 追上最后发布的序号(`ClientSession::WaitForApplyToCatchUp`,与 `glFinish` 同一种强制等待)。 -- 块的写分两段、夹着记录发布:发射前写 verb 序号、撤 server 戳与 verb 名,发射后做残余字段遍历;发出的记录 apply 时要读这块,一次等待盖不住两段。 -- `ClientSession::RefusePipeInputsTouchWhileApplierOwnsIt` 查的是事实(apply 线程不在 applier 内),不采信调用方的声明;漏掉等待即 `Fatal{RoleViolation, "gPipeInputs"}`。 -- lockstep 下 `appliedSeq` 已在最后发布的序号上,等待立即返回。client 与 server 用不同块时(`MGPipeBlocksAreDistinct`:分角色演练或 spawn),client 只写自己的块、不必等待,server 块的戳只由 `PipeApplier::LeaveApplier` 清除。 +- The validate order is fill → emit → park; during fill the apply thread may still be executing previously published unbarriered records, so before every write `QuiesceApplierBeforeFill` first waits for the applier to catch up with the last published seq (`ClientSession::WaitForApplyToCatchUp`, the same kind of forced wait as `glFinish`). +- The block's write is split into two parts with the record publication in between: before emission write the verb serial and withdraw the server stamp and the verb name; after emission do the residual field walk; the emitted record reads this block when it is applied, and one wait cannot cover both parts. +- `ClientSession::RefusePipeInputsTouchWhileApplierOwnsIt` checks the fact (the apply thread is not inside the applier) and does not trust the caller's declaration; a missing wait is `Fatal{RoleViolation, "gPipeInputs"}`. +- Under lockstep `appliedSeq` is already on the last published seq, so the wait returns immediately. When client and server use different blocks (`MGPipeBlocksAreDistinct`: role drills or spawn), the client writes only its own block and need not wait, and the server block's stamp is cleared only by `PipeApplier::LeaveApplier`. # define MGB_CTX (&::MobileGL::MG_Pipe::gPipeInputs) #else # define MGB_CTX (::MG_State::pGLContext) #endif ``` -三步:A 别名(P1,机械替换 + 逐 verb 类填充点,`nm` 不变)→ B 推送(P2,tracker 填 `gPipeInputs`,verify 构建逐 draw 比对快照版)→ C 句柄化(P3a–P4a、P7,`SharedPtr<前端对象>` → 句柄 + 描述符,写回变回调)。poison 是**逐 verb 世代**:读一个当前 verb 未填的字段是 `Fatal{UnmigratedPipeInput, "@"}`。 +Three steps: A alias (P1, mechanical replacement + per-verb-class fill points, `nm` unchanged) → B push (P2, the tracker fills `gPipeInputs`, verify builds compare against the snapshot version draw by draw) → C handle conversion (P3a–P4a, P7, `SharedPtr` → handle + descriptor, writeback becomes a callback). Poison is **per-verb generation**: reading a field not filled for the current verb is `Fatal{UnmigratedPipeInput, "@"}`. -**P13 收尾**:pull 分支与宏一起删掉(W3b,`MGB_CTX` 不再存在,后端只经 `gPipeInputs` 与 applier 记录取状态);单进程也走记录臂(W4–W5),后端的前端对象臂与前端键 twin 入口删除(W6)——Espryt 的 twin 表只收 client 铸好的句柄,对象死亡通知带句柄、按句柄释放(与 server 的 `object_death` 同一释放)。 +**P13 wrap-up**: the pull branch is deleted together with the macro (W3b, `MGB_CTX` no longer exists, and the backend takes state only through `gPipeInputs` and applier records); the monolith also goes through the record arm (W4–W5), and the backend's frontend-object arm and frontend-keyed twin entries are deleted (W6) — Espryt's twin table only accepts client-minted handles, object death notifications carry a handle, and release is by handle (the same release as the server's `object_death`). ### 9.3 Track V / Track H -Track V(值类型:render state、pixel store、capability 位、标量)是机械迁移;Track H(167 个 `SharedPtr` 读点)是真活。74% 的读点是翻译输入,所以"bump 一个版本让 server 自己拉"行不通,值本身必须过去。 +Track V (value types: render state, pixel store, capability bits, scalars) is a mechanical migration; Track H (167 `SharedPtr` read sites) is the real work. 74% of the read sites are translation inputs, so "bump a version and let the server pull" does not work; the values themselves must go over. -### 9.4 残余值块 +### 9.4 Residual value block -迁移期临时调用 `SetResidualValueState`(`ResidualValueBlock`):尺寸只降不升(1248 → 8,只剩 `CapabilityBits`),P13 W3c 删除——op 46 退役为拒绝行,capability 交叉核对交给 verify 比较器;`set_context_values` 携带剩下的值类字段(单进程也发,W4d / W8)。 +During migration, `SetResidualValueState` (`ResidualValueBlock`) is called temporarily: its size only shrinks, never grows (1248 → 8, only `CapabilityBits` left), and it is deleted in P13 W3c — op 46 retires as a rejecting line, and the capability cross-check goes to the verify comparator; `set_context_values` carries the remaining value-class fields (also sent under monolith, W4d / W8). -### 9.5 身份 memo 的重键 +### 9.5 Re-keying identity memos -`{slot, gen}` + 显式 destroy 让 21 条身份 memo 中 **11 条直接删除**、2 条的去抖搬到 client(§5.4)、7 条重键成更便宜的比较、1 条(D18)不动。统一事实:进 memo 键的版本计数器要么会回绕,要么根本不被它害怕的 mutation bump,身份比较是堵洞的补丁。 +`{slot, gen}` + explicit destroy means that of the 21 identity memos, **11 are deleted outright**, 2 move their debounce to the client (§5.4), 7 are re-keyed to a cheaper comparison, and 1 (D18) is untouched. The unified fact: a version counter that enters a memo key either wraps or is simply not bumped by the mutation it fears; identity comparison is a patch over the hole. -### 9.6 A/B 与口径收窄 +### 9.6 A/B and narrowing the criteria -`MOBILEGL_PIPE_PUSH` 子系统位图在阶段 B 是真 A/B;阶段 C 之后位清零时后端仍跑重键后的代码,所以**编译期** `MOBILEGL_PIPE_LEGACY_MEMOS` 曾保留 pre-handle 臂。P13 结束了这段:`LEGACY_MEMOS` 与 pre-handle 臂删除,位 0–13 固定开、清位即启动期具名拒绝(原 Off 车道改为这条拒绝的阴性对照),只剩位 63 可设。位依赖两侧都拒(客户端族门里**根本不发射**,否则会"客户端已清 dirty、服务端却走旧臂"而丢上传);没有消费者的后端一条不发。 +`MOBILEGL_PIPE_PUSH`'s subsystem bitmap is a real A/B in phase B; after phase C, when the bits are cleared, the backend still runs the re-keyed code, so the **compile-time** `MOBILEGL_PIPE_LEGACY_MEMOS` once preserved the pre-handle arm. P13 ended this: `LEGACY_MEMOS` and the pre-handle arm are deleted, bits 0–13 are permanently on, and clearing a bit is a named refusal at startup (the original Off lane becomes the negative control for this refusal), leaving only bit 63 settable. Dependencies between bits are refused on both sides (the client family gate **does not emit at all**, otherwise "the client has cleared dirty while the server takes the old arm" would drop uploads); a backend with no consumers sends nothing. -## 10. server 侧 +## 10. Server side -### 10.1 对象表与 applier +### 10.1 Object tables and the applier -`MG_Remote/Server/PipeApplier`:解码 → 更新对象表与 `PipeInputs` → 调后端。单进程(P13 起)是同一记录臂少了编解码与环:状态记录经 `PipeRoute` 的单进程表直进 applier,verb 记录由 `MG_Impl/Pipe/Verb` 的发射器交给本进程的 `MG_Backend/Record/RecordVerbSink`。server 不持有 buffer 的完整副本(只有 staged shadow)、不持有前端对象图;任何传输下都不得有 `SharedPtr` 或裸前端指针跨过 applier 边界(P5c 角色守卫、P5e 规则 F)。`InProcessTransport` 与 spawn 走完全相同的编解码路径。 +`MG_Remote/Server/PipeApplier`: decode → update the object tables and `PipeInputs` → call the backend. Monolith (since P13) is the same record arm minus the codec and the ring: state records go straight into the applier through `PipeRoute`'s monolith table, and verb records are handed by the emitters in `MG_Impl/Pipe/Verb` to this process's `MG_Backend/Record/RecordVerbSink`. The server does not hold a full copy of buffers (only the staged shadow) and does not hold the frontend object graph; under any transport, no `SharedPtr` or raw frontend pointer may cross the applier boundary (P5c role guard, P5e rule F). `InProcessTransport` and spawn go through exactly the same codec path. -### 10.2 monolith 侧的净收益 +### 10.2 Net gain on the monolith side -即使 IPC 永不上线:复用地址 ABA 一整类不可表达;FBO → program 排序 hazard 消失;`SwapchainObject` 写 `MG_Impl` 的分层倒置消失;`inproc` = 渲染线程。monolith 净代码量是增加的,论据只看逐线程 CPU。 +Even if IPC never ships: a whole class of address-reuse ABA becomes inexpressible; the FBO → program ordering hazard disappears; the layering inversion of `SwapchainObject` writing into `MG_Impl` disappears; `inproc` = the render thread. The monolith's net line count increases; the argument looks only at per-thread CPU. -### 10.3 索引宿主镜像(`Server/IndexHostMirror`,P8,待重裁) +### 10.3 Index host mirror (`Server/IndexHostMirror`, P8, pending a new ruling) -设计:`kCapNeedsHostIndexBytes` 下,server 从本来就要收的 `ResourceCreate/Respecify/SubData` 流增量维护 element-array buffer 的宿主镜像,零额外流量;预算 `MOBILEGL_PIPE_INDEX_MIRROR_MB`(默认 64),超预算退化为逐 draw 经 `MGHostSpan` 传送。**P6 的 a6 审计实测宿主索引 span 无 producer、client 索引已是 owned buffer**,所以 P8 要按真实消费者重新裁定,不照抄本节(见 git 历史)。 +Design: under `kCapNeedsHostIndexBytes`, the server incrementally maintains a host mirror of element-array buffers from the `ResourceCreate/Respecify/SubData` stream it has to receive anyway, with zero extra traffic; the budget is `MOBILEGL_PIPE_INDEX_MIRROR_MB` (default 64), and beyond the budget it degrades to transporting via `MGHostSpan` per draw. **P6's a6 audit measured that host index spans have no producer and client indices are already owned buffers**, so P8 must be ruled again against real consumers rather than copying this section (see the git history). diff --git a/docs/Disaggregated/design/06-transport.md b/docs/Disaggregated/design/06-transport.md index 7ffd1347..47e6a5d1 100644 --- a/docs/Disaggregated/design/06-transport.md +++ b/docs/Disaggregated/design/06-transport.md @@ -1,95 +1,95 @@ -# 传输与数据面(原 ARCHITECTURE §11) +# Transport and data plane (formerly ARCHITECTURE §11) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design points and the index of all chapters are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; an `ARCHITECTURE.md §N` in a code comment is found by its number here. -## 11. 传输与数据面(`MobileGL/MG_Remote/`) +## 11. Transport and data plane (`MobileGL/MG_Remote/`) -### 11.1 段 +### 11.1 Segments -| 段 | 拥有者 | 默认 | 内容 | +| Segment | Owner | Default | Contents | |---|---|---|---| -| `SEG_CMD` | client(server 只读) | 8 MiB | `RingControl` 页 + POD 记录 + 小内联负载 | -| `SEG_STAGE` | client | 32 MiB | bulk 字节:buffer / 纹理 subdata、UBO、client 数组、persistent-map 脏块 | -| `SEG_REPLY` | server | 16 MiB,8 × 2 MiB slot | readback 像素、acceptance 答案(ID-47) | -| `SEG_EVENT` | server | 256 KiB SPSC ring | 回调事件 | -| `SEG_SHADOW` / `SEG_ADOPT` | client / server | — | 零拷贝 shadow(Phase 2)/ ≥16 MiB 采纳(P11);stream 数据面上具名拒绝(`MG_Remote/Transport/AdoptTier.cpp`,握手期,P11 A1) | +| `SEG_CMD` | client (server read-only) | 8 MiB | `RingControl` page + POD records + small inline payloads | +| `SEG_STAGE` | client | 32 MiB | bulk bytes: buffer / texture subdata, UBOs, client arrays, persistent-map dirty blocks | +| `SEG_REPLY` | server | 16 MiB, 8 × 2 MiB slots | readback pixels, acceptance answers (ID-47) | +| `SEG_EVENT` | server | 256 KiB SPSC ring | callback events | +| `SEG_SHADOW` / `SEG_ADOPT` | client / server | — | zero-copy shadow (Phase 2) / ≥16 MiB adoption (P11); refused by name on the stream data plane (`MG_Remote/Transport/AdoptTier.cpp`, during the handshake, P11 A1) | -段在同机上由 `ShmSegment` 创建(Android `ASharedMemory`、Linux `memfd`、Windows `CreateFileMappingW`),描述符经 `SCM_RIGHTS` 传递;stream 数据面上两端各持一份同尺寸的私有段(§11.9)。 +On the same machine the segments are created by `ShmSegment` (Android `ASharedMemory`, Linux `memfd`, Windows `CreateFileMappingW`), and descriptors are passed with `SCM_RIGHTS`; on the stream data plane each end holds a private segment of the same size (§11.9). -### 11.2 `RingControl`(`Ring.h`) +### 11.2 `RingControl` (`Ring.h`) -一页 4 KiB,每个争用组一条 cache line,按写者分组(P6 lk):producer 线 `cmdHead` / `submittedSeq`;consumer 线两个 tail;四个 consumer 写的水位收成 `Progress`(`appliedSeq` / `retiredSeq` / `completedFrameSerial` / `presentAckSerial`);最后是 epoch、generation、park 标志与 `eventRingFull` / `eventDropped`。游标是单调字节计数、2 的幂掩码、永不重置;pad 记录处理 wrap;不可能的头 → `Fatal{ProtocolCorruption}`。 +One 4 KiB page, one cache line per contention group, grouped by writer (P6 lk): the producer line holds `cmdHead` / `submittedSeq`; the consumer line holds two tails; the four watermarks written by the consumer are collected into `Progress` (`appliedSeq` / `retiredSeq` / `completedFrameSerial` / `presentAckSerial`); finally the epoch, generation, park flags and `eventRingFull` / `eventDropped`. Cursors are monotonic byte counts with a power-of-two mask and are never reset; pad records handle the wrap; an impossible head → `Fatal{ProtocolCorruption}`. -#### 11.2.1 五个水位 +#### 11.2.1 The five watermarks -| 水位 | 由谁推进 | 含义 | +| Watermark | Advanced by | Meaning | |---|---|---| -| `submittedSeq` | producer,发布之后 | 诊断量(client 领先 server 多少),没有人等它;放在 producer 的 cache line 上,`LinkProgress` 因此单写者 | -| `appliedSeq` | consumer,每 apply 一条记录 +1 | verb barrier 与每个 reply 等待读它,所以不得批量:批量会让等待方卡在已完成的工作上,或在未完成的工作上醒来 | -| `retiredSeq` | consumer,记录引用的 `SEG_STAGE` 字节用完后 | staging 分配器只在它之后回收;不超过 `appliedSeq` | -| `completedFrameSerial` | server,present 完成时 | 回收与老化等它;比 `appliedSeq` 落后一个 GPU 深度,不得混用 | -| `presentAckSerial` | server,归还 present credit 时 | present 节流等它;唯一限制延迟而非字节的背压 | +| `submittedSeq` | producer, after publishing | a diagnostic (how far the client is ahead of the server), nobody waits on it; it sits on the producer's cache line, so `LinkProgress` stays single-writer | +| `appliedSeq` | consumer, +1 per applied record | verb barriers and every reply wait read it, so it must not batch: batching leaves a waiter stuck on work that has already completed, or wakes it on work that has not | +| `retiredSeq` | consumer, once the `SEG_STAGE` bytes a record references are done with | the staging allocator reclaims only after it; never beyond `appliedSeq` | +| `completedFrameSerial` | server, when present completes | reclamation and aging wait on it; it trails `appliedSeq` by one GPU depth and must not be mixed with it | +| `presentAckSerial` | server, when the present credit is returned | present throttling waits on it; the only backpressure that limits latency rather than bytes | -规则(`SessionRings.h` 的 `Watermark` 是唯一实现):所有等待用 `>=`,两侧都可能一次前进多步,`==` 会错过唤醒。水位只许晚发布、不许早发布:晚只是多等,早会让等待方静默使用尚未发生的工作,环上没有校验能发现;除 `appliedSeq` 外都可惰性发布,回退是 `Fatal{ProtocolCorruption}`。wrap 填充(`kRecPad`)不推进 seq:seq 就是 reply slot 的 id,只有一侧计数填充时两侧序号每次 wrap 偏一、静默读到别的调用的答案,所以两侧都在计数前跳过它(`RingConsumer::Pop`)。 +The rule (`Watermark` in `SessionRings.h` is the only implementation): every wait uses `>=`, since either side may advance several steps at once and `==` would miss the wakeup. A watermark may only be published late, never early: late just means waiting longer, while early makes a waiter silently use work that has not happened, and no check on the ring can detect it; all but `appliedSeq` may be published lazily, and going backward is `Fatal{ProtocolCorruption}`. The wrap padding (`kRecPad`) does not advance seq: seq is the reply slot id, and if only one side counted the padding the two sides' sequence numbers would be off by one on every wrap and silently read another call's answer, so both sides skip it before counting (`RingConsumer::Pop`). -### 11.3 双向 doorbell(`Doorbell.h`) +### 11.3 Bidirectional doorbell (`Doorbell.h`) -两个方向都是"先自旋、再置 parked、再阻塞",发布方仅当对端 parked 时敲;丢失唤醒由两个 `seq_cst` fence 关闭。`CondVarDoorbell`(同进程,带 `Kill()`)与 `SocketDoorbell`(跨进程,对端关闭即死亡检测)。stream 数据面上门铃是本地条件变量,由读线程敲。 +Both directions do "spin first, then set parked, then block", and the publisher rings only when the peer is parked; lost wakeups are closed off by two `seq_cst` fences. `CondVarDoorbell` (same process, with `Kill()`) and `SocketDoorbell` (across processes, where the peer closing is the death detection). On the stream data plane the doorbell is a local condition variable, rung by the read thread. -#### 11.3.1 丢失唤醒为什么靠两道 fence +#### 11.3.1 Why lost wakeups rest on two fences -等待方:置 park 标志 → `std::atomic_thread_fence(seq_cst)` → 重测条件(`Doorbell::Wait`);通知方:发布水位 → 同样的 fence → 读 park 标志(`NotifyIfParked`)。两道 fence 都在 seq_cst 全序里、必有先后,按 [atomics.order] 至少一侧看得见另一侧的写,所以标志自身的读写可以是 relaxed。 +Waiter: set the park flag → `std::atomic_thread_fence(seq_cst)` → re-test the condition (`Doorbell::Wait`); notifier: publish the watermark → the same fence → read the park flag (`NotifyIfParked`). Both fences are in the seq_cst total order and must have an order, so by [atomics.order] at least one side sees the other side's writes, and the flag's own reads and writes can be relaxed. -只把标志的 store / load 改成 seq_cst 不够:Dekker 论证要求四个访问都在全序里,而水位发布是 release store(`RingProducer::Publish`)、条件重测是 acquire load。x86 上 release store 是普通 MOV,还停在 store buffer 里时,对标志的普通 MOV 读就可能读到 0,通知方于是不敲门铃,等待方在旧水位上永久 park;ARMv8 上 STLR→LDAR 是 RCsc,只是碰巧没事。所以两道 fence 都不可删,且 `NotifyIfParked` 必须在水位发布之后调用:fence 只约束它之前的访问。 +Making only the flag's store / load seq_cst is not enough: the Dekker argument requires all four accesses to be in the total order, while the watermark publication is a release store (`RingProducer::Publish`) and the condition re-test is an acquire load. On x86 a release store is a plain MOV, and while it is still in the store buffer a plain MOV read of the flag may read 0, so the notifier does not ring the doorbell and the waiter parks forever on the old watermark; on ARMv8 STLR→LDAR is RCsc and merely happens to be fine. So neither fence can be removed, and `NotifyIfParked` must be called after the watermark publication: a fence only orders the accesses before it. -### 11.4 控制面(`protocol.fbs`、`Framing.h`、`ITransport.h`) +### 11.4 Control plane (`protocol.fbs`, `Framing.h`, `ITransport.h`) -- 一份 FlatBuffers schema:热路径是 `struct` 直接进 ring(与 POD 逐条 `static_assert` 对齐);罕见 / 变长 / 需演进的走控制连接的 `CtrlMsg`(`Hello`、`Welcome`、`Refuse`、`CapsSnapshot`、`SurfaceOp/SurfaceReply`、`SessionFault`、`LogLine` …),union tag 只追加,控制修订号钉在 `sha256(protocol.fbs)` 上。 -- 生成物提交进树,CI `flatc-check` 重生成并 diff;codegen 不进默认构建图。 -- 封帧 `[u32 'MGLF'][u32 len][payload]`,64 MiB 上限,读时校验,坏帧立即闩住失败。 +- One FlatBuffers schema: the hot path uses `struct`s that go straight into the ring (aligned one by one with the POD records by `static_assert`); the rare / variable-length / evolving cases go through `CtrlMsg` on the control connection (`Hello`, `Welcome`, `Refuse`, `CapsSnapshot`, `SurfaceOp/SurfaceReply`, `SessionFault`, `LogLine` …), union tags are append-only, and the control revision is pinned to `sha256(protocol.fbs)`. +- The generated output is committed to the tree, and the CI `flatc-check` regenerates it and diffs; codegen is not in the default build graph. +- Framing is `[u32 'MGLF'][u32 len][payload]`, with a 64 MiB cap, validated on read, and a bad frame latches the failure immediately. -### 11.5 WAR 危害、拷贝账与背压 +### 11.5 WAR hazards, the copy accounting and backpressure -Phase 1(今天):GL 调用时刻把字节拷进 stage slot,slot 到 apply 越过它为止不可变,危害按构造消除,代价一次 memcpy;Phase 2(`SEG_SHADOW` 零拷贝)未做。server 没有第二份 `BufferObject`,不存在中间拷贝。分配失败升级:扩容 → 对最老未退休批次有界等待 → 硬 drain + generation bump(之后 tracker 全部重推)。 +Phase 1 (today): the bytes are copied into a stage slot at the moment of the GL call, the slot is immutable until apply passes it, hazards are eliminated by construction, and the cost is one memcpy; Phase 2 (`SEG_SHADOW` zero copy) is not done. The server has no second `BufferObject`, so there is no intermediate copy. Allocation failure escalates: grow → bounded wait on the oldest unretired batch → hard drain + generation bump (after which the tracker re-pushes everything). -### 11.6 publish、序号与 credit +### 11.6 Publish, sequence numbers and credit -- 每条记录 release-store `cmdHead`,仅当 consumer parked 时敲门铃;显式门铃点:`present`、`kNeedsAck`、`eglMakeCurrent`、`glFlush`、stage 余量不足、轮询类入口。 -- seq = 记录序数;字节 credit 与 present credit 两个独立窗口。 -- **等待规则由 `WaitClass` 列决定(P5e)**:`kWaitReply` / `kWaitPresent` / `kWaitApplied` / `kWaitNone`;run-ahead 武装时 `kWaitNone` 发布即返回。barriered 谓词(`MGPipeBarriered`)client 与 server 用同一个函数、同一份数据算。 -- 强制等待点:`MapBuffer(READ)` / `GetBufferSubData` 源走 `SyncGpuWrites`;`glFinish` = 等 `appliedSeq` 追上再排空反向通道;每个 `Server*` EGL forwarder 之前等一次。`glGetError` 最多晚一个 present credit。 +- Every record release-stores `cmdHead`, and the doorbell is rung only when the consumer is parked; explicit doorbell points: `present`, `kNeedsAck`, `eglMakeCurrent`, `glFlush`, insufficient stage headroom, and polling-style entry points. +- seq = the record ordinal; byte credit and present credit are two independent windows. +- **The wait rule is decided by the `WaitClass` column (P5e)**: `kWaitReply` / `kWaitPresent` / `kWaitApplied` / `kWaitNone`; with run-ahead armed, `kWaitNone` returns as soon as it publishes. The barriered predicate (`MGPipeBarriered`) is computed with the same function and the same data on the client and on the server. +- Forced wait points: `MapBuffer(READ)` / the `GetBufferSubData` source goes through `SyncGpuWrites`; `glFinish` = wait until `appliedSeq` catches up, then drain the reverse channel; wait once before every `Server*` EGL forwarder. `glGetError` may lag by at most one present credit. -#### 11.6.1 barriered 谓词的条款 +#### 11.6.1 The terms of the barriered predicate -`MGPipeBarriered(op, payload, applierState)`(`MG_Pipe/PipeApply.h`)由 server 的 `ApplyOne` 计算,决定这条记录能否读 client 内存;client 不调用它,而是在发布前对同样的条款求值(`ClientSession` 的等待规则读 `WaitClass` 列,`PipeFill.cpp` 的 `ClientVerbIsBarriered` 另判 XFB)。两侧答案一旦不同,失败是静默的(client 继续跑,server 读到已经变了的值),所以条款只读线上可见的数据:静态 `WaitClass` 列、记录自身的 payload、ring 上更早的记录写进 applier 的状态。条款只有三条: +`MGPipeBarriered(op, payload, applierState)` (`MG_Pipe/PipeApply.h`) is computed by the server's `ApplyOne` and decides whether this record may read client memory; the client does not call it, but evaluates the same terms before publishing (the wait rule in `ClientSession` reads the `WaitClass` column, and `ClientVerbIsBarriered` in `PipeFill.cpp` separately decides XFB). If the two sides' answers ever differ, the failure is silent (the client keeps running and the server reads a value that has already changed), so the terms read only data visible on the wire: the static `WaitClass` column, the record's own payload, and the state that earlier records on the ring wrote into the applier. There are only three terms: -1. `WaitClass != kWaitNone`; -2. 打开的 XFB span 内的 `kCtxVerb`(XFB 保持 lockstep); -3. 带 `kDrawClientArrays` 的 `draw_vbo`:run-ahead 下 client 在发布前就拒绝它,此条只为 lockstep 臂而在,使谓词完备。 +1. `WaitClass != kWaitNone`; +2. a `kCtxVerb` inside an open XFB span (XFB stays lockstep); +3. a `draw_vbo` with `kDrawClientArrays`: under run-ahead the client refuses it before publishing, so this term exists only for the lockstep arm, to make the predicate complete. -新条款必须在同一次改动里同时加进这个函数与 client 侧的对应判断,不能只在一侧加。评判候选条款要问**哪条臂为它付代价**,而不是它让哪条车道变绿:曾为让 Espryt 间接 multi-draw 档读 `GL_DRAW_INDIRECT_BUFFER` 绑定合法化,把所有普通 multi-draw 升级为 barriered,于是默认档的每次 `glMultiDraw*` 都多一次会合,而这次读只发生在两个可选档里;最终改由做绑定的一侧按句柄回答(`MultiDraw.cpp` 的 `BoundDrawIndirectBufferId`),撤回了该条款。 +A new term must be added to this function and to the corresponding client-side decision in the same change, never on one side only. Judging a candidate term means asking **which arm pays for it**, not which lane it turns green: once, to make the Espryt indirect multi-draw tier's read of `GL_DRAW_INDIRECT_BUFFER` bindings legitimate, every ordinary multi-draw was upgraded to barriered, so every `glMultiDraw*` in the default tier gained one more rendezvous, while that read happens only in two optional tiers; in the end the side that does the binding answers by handle instead (`BoundDrawIndirectBufferId` in `MultiDraw.cpp`), and the term was withdrawn. -### 11.7 事件回传与溢出 +### 11.7 Event return and overflow -client 在 `glGetError`、query / sync 查询、`eglSwapBuffers`、buffer 回读与每轮等待循环中排空 `SEG_EVENT`。日志有损;语义事件无损:环满时 server 置 `eventRingFull`、在记录边界停 apply、敲 client,client 排空后清标志并敲回(两半都在,才不死锁)。run-ahead 下 producer 阻塞等排空,整笔预算 `MOBILEGL_IPC_EVENT_WAIT_MS`;client 不排空 / 已走 / 会话停止 → `ReverseChannelForfeit{…}` 弃投并闩住(Ph PH-6),而不是 `Fatal` 打掉 server。不发布 `kCapRunAheadApply` 的 server(lockstep 臂)保留 P5c 的 Fatal。 +The client drains `SEG_EVENT` in `glGetError`, query / sync queries, `eglSwapBuffers`, buffer readback, and each wait-loop round. Logs are lossy; semantic events are lossless: when the ring is full the server sets `eventRingFull`, stops applying at a record boundary, and rings the client; after draining, the client clears the flag and rings back (both halves are present, so there is no deadlock). Under run-ahead the producer blocks waiting for the drain, with a whole budget of `MOBILEGL_IPC_EVENT_WAIT_MS`; if the client does not drain / has gone away / the session stops → `ReverseChannelForfeit{…}` forfeits delivery and latches (Ph PH-6), instead of a `Fatal` taking down the server. A server that does not publish `kCapRunAheadApply` (the lockstep arm) keeps the P5c Fatal. -### 11.8 fence 与无 present 负载(P10) +### 11.8 Fences and present-free workloads (P10) -fence 完成度必须来自真的逐 fence 退休,不是 present 水位(DirectGLES 的 `g_completedFrameSerial` 今天只在 `Present` 前进);无 present 循环需要 server 插非 present fence tick。Magma 那半已随 run-ahead 落地。 +Fence completion must come from real per-fence retirement, not from the present watermark (`g_completedFrameSerial` in DirectGLES today only advances in `Present`); a present-free loop needs the server to insert a non-present fence tick. The Magma half has landed with run-ahead. -### 11.9 传输栈的两根轴(P6.5) +### 11.9 The two axes of the transport stack (P6.5) -终局(2026-09-22):client 与 server 可在不同机器、不同 OS / 架构上经 TCP 连接,同机 `spawn` 保留。传输栈拆成**两根独立可选、握手协商、可混搭**的轴,上层只见两个接口: +The end goal (2026-09-22): the client and the server may connect over TCP from different machines and different OSes / architectures, and same-machine `spawn` is kept. The transport stack is split into **two independently selectable, handshake-negotiated, mixable** axes, and the layers above see only two interfaces: -| 轴 | 接口 | 实现 | 选项(`MOBILEGL_IPC_CONTROL` / `MOBILEGL_IPC_DATA`) | +| Axis | Interface | Implementations | Options (`MOBILEGL_IPC_CONTROL` / `MOBILEGL_IPC_DATA`) | |---|---|---|---| -| 控制面 | `ITransport`(只承载控制帧,不承载描述符) | `SocketTransport` | `fork`(继承 fd)、`unix:`、`tcp://host:port` | -| 数据面 | `ILink`(记录预留 / 提交、水位、reply、event、span 解析) | `ShmLink`(共享段 + `RingControl` + 门铃)、`StreamLink`(分块封帧,水位与 reply 变消息,发送窗口) | `shm`、`stream`、`auto` | +| control plane | `ITransport` (carries only control frames, never descriptors) | `SocketTransport` | `fork` (inherited fd), `unix:`, `tcp://host:port` | +| data plane | `ILink` (record reservation / commit, watermarks, reply, event, span resolution) | `ShmLink` (shared segment + `RingControl` + doorbell), `StreamLink` (chunked framing, watermarks and replies become messages, send window) | `shm`, `stream`, `auto` | -- 配对在会话建立时选定一次;`LinkTerms`(数据面、窗口尺寸、`maxReplyBytes` …)由 **server 陈述**,client 请求可被钳制。 -- 共享段交付与控制面解耦:`ShmLink` 自带 AF_UNIX aux 汇合名,在 `Welcome` 里公布,所以同机"TCP 控制 + 共享段数据"是合法配对。`auto` 的判据是**段实际交付成功**,回落到 `stream` 必须具名进日志。 -- **上层零链路种类分支**:`ShmLink` / `StreamLink` / `RingControl` 等只出现在 `Transport/` 与其测试(纯度 grep 门);角色谓词回答"谁在哪个进程",不回答"用什么链路"。 -- 两端是不同二进制:`wireFingerprint`(`PipeFields.def` 派生的逐成员布局摘要 + 目录摘要 + 字节序 / 指针宽度)永远比较;`buildFingerprint` 只在 `Dial == Fork`(或 `MOBILEGL_IPC_REQUIRE_SAME_BUILD=1`)下比较;不一致是 `Refuse`,不是 abort。 -- TCP 上每条 `kWaitReply` 就是一个 RTT、`SEG_STAGE` 字节对的是 30–100 MB/s 的链路:这两列从"记录项"变成可行性数(开放问题 19、20)。 +- The pairing is chosen once at session setup; `LinkTerms` (data plane, window sizes, `maxReplyBytes` …) is **stated by the server**, and the client's request may be clamped. +- Shared-segment delivery is decoupled from the control plane: `ShmLink` carries its own AF_UNIX aux rendezvous name, announced in `Welcome`, so "TCP control + shared-segment data" on the same machine is a valid pairing. The `auto` criterion is **that the segment actually delivered successfully**, and a fallback to `stream` must be named in the log. +- **Zero link-kind branches above**: `ShmLink` / `StreamLink` / `RingControl` and the like appear only in `Transport/` and its tests (a purity grep gate); role predicates answer "who is in which process", not "what link is used". +- The two ends are different binaries: `wireFingerprint` (the per-member layout digest derived from `PipeFields.def` + the catalog digest + byte order / pointer width) is always compared; `buildFingerprint` is compared only under `Dial == Fork` (or `MOBILEGL_IPC_REQUIRE_SAME_BUILD=1`); a mismatch is a `Refuse`, not an abort. +- Over TCP every `kWaitReply` is one RTT, and the `SEG_STAGE` bytes face a 30–100 MB/s link: these two columns turn from "record items" into feasibility numbers (open questions 19, 20). -第一波(全 TCP 控制 + stream 数据)已落地;同机混搭(nd `auto` / sd)是第二波。细节与契约见 git 历史。 +The first wave (all-TCP control + stream data) has landed; same-machine mixing (nd `auto` / sd) is the second wave. Details and contracts are in the git history. diff --git a/docs/Disaggregated/design/07-memory-readback-verification.md b/docs/Disaggregated/design/07-memory-readback-verification.md index 81c4b9cd..1151874b 100644 --- a/docs/Disaggregated/design/07-memory-readback-verification.md +++ b/docs/Disaggregated/design/07-memory-readback-verification.md @@ -1,72 +1,72 @@ -# persistent map、回读与验证(原 ARCHITECTURE §12–§13) +# Persistent map, readback and verification (formerly ARCHITECTURE §12–§13) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design points and the index of all chapters are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; an `ARCHITECTURE.md §N` in a code comment is found by its number here. -## 12. persistent map 与 ≥16 MiB 采纳 +## 12. Persistent map and ≥16 MiB adoption -`AcquirePersistentMap` 是永久的地址空间捐赠(≥16 MiB 可变 store 自动采纳,MC 26.3 p99 163 → 21 ms),整个 monolith 改造期不动(D-B4)。拆分下三档由 POST 探针选择(spike B 实测): +`AcquirePersistentMap` is a permanent address-space donation (a mutable store of ≥16 MiB is adopted automatically, MC 26.3 p99 163 → 21 ms), unchanged through the whole monolith rework (D-B4). Under the split, the POST probe chooses among three tiers (measured in spike B): -| 档 | 形态 | 结论 | +| Tier | Shape | Conclusion | |---|---|---| -| T0 | client 分配 `AHardwareBuffer` BLOB,server 导入(Vulkan / GLES) | 唯一在两台设备、两个后端上都完整读写的档(P11 主攻) | -| T1 | server 导出 opaque fd | 仅 Adreno 的 Vulkan 路径 | -| T2 | 拒绝,client 侧推送 | 永久正确回退;**今天 split 用的档**(`MOBILEGL_IPC_ADOPT_TIER=2`),stream 数据面上强制(P11 A1:两端握手时 `Transport::SettleAdoptTierAtHandshake` 对 0/1 打一行 `Refuse{AdoptTierOnStream}` 并走 T2;共享段上 client 握手期 `Fatal{UnimplementedAdoptTier}`,`CONTRACT-P11.md` §1) | +| T0 | the client allocates an `AHardwareBuffer` BLOB, the server imports it (Vulkan / GLES) | the only tier that reads and writes fully on both devices and both backends (the P11 main thrust) | +| T1 | the server exports an opaque fd | only the Adreno Vulkan path | +| T2 | refuse, push on the client side | the permanently correct fallback; **the tier today's split uses** (`MOBILEGL_IPC_ADOPT_TIER=2`), forced on the stream data plane (P11 A1: at handshake `Transport::SettleAdoptTierAtHandshake` prints one `Refuse{AdoptTierOnStream}` line for 0/1 and goes T2; on a shared segment the client gets `Fatal{UnimplementedAdoptTier}` during the handshake, `CONTRACT-P11.md` §1) | -T2 下 client 侧推送三件套:不做 map/unmap 命令对(payload 带 `hasLiveHostWrites`);在每个 validate 点按 64 KiB 块推送可达的已映射 buffer,脏页追踪 + 哈希抑制只发变化的块(P5d);门 `PersistentCoherentMapScenario`。`mpr` 数的是每一次 `MapPersistent` 发射(铸成或拒绝都算),所以在 monolith 下也可断言。 +Under T2 the client-side push has three parts: no map/unmap command pair (the payload carries `hasLiveHostWrites`); at every validate point, push the reachable mapped buffers in 64 KiB blocks, with dirty-page tracking + hash suppression sending only the changed blocks (P5d); the gate is `PersistentCoherentMapScenario`. `mpr` counts every `MapPersistent` emission (a mint or a refusal both count), so it can be asserted under the monolith too. -### 12.1 采纳档的握手期结算 +### 12.1 Settling the adoption tier at handshake -档在握手期、第一条 `map_persistent` 之前,由知道数据面的一侧结算(`MG_Remote/Transport/AdoptTier.h`)。T0 用不了从不是 `Fatal`,而是 T2 加一行:`MOBILEGL_IPC_ADOPT_TIER=0` 时是具名行,未设时只打 MGLOG_D,照样计数。 +The tier is settled during the handshake, before the first `map_persistent`, by the side that knows the data plane (`MG_Remote/Transport/AdoptTier.h`). T0 being unusable is never a `Fatal`; it is T2 plus one line: a named line when `MOBILEGL_IPC_ADOPT_TIER=0`, and only an MGLOG_D when unset, counted either way. -| 数据面 | 一侧 | knob 0 / 未设 | knob 1 | +| Data plane | Side | knob 0 / unset | knob 1 | |---|---|---|---| -| stream | 两端 | 只有 T2(不共享内存);knob 0 打 `Refuse{AdoptTierOnStream, "T0"}` | `Refuse{AdoptTierOnStream, "T1"}`,T2 | -| 共享段 | client | 在 `Hello` 的 `LinkTerms.adoptTier` 请求 T0(0;未设为 `kAdoptAskT0Default`);是否真跑 T0 在第一条 `map_persistent` 时读 `kCapAdoptT0`(`ClientSession::AdoptT0`) | `Refuse{AdoptTierClosed, "T1"}`,请求 T2 | -| 共享段 | server | 不看自己的 knob:按 client 的请求,在第一次原生 bind 时批准(`ServerSession::SettleAdoptT0AtBind`,之后的 `CapsSnapshot` 带 `kCapAdoptT0`)或具名说明原因 | 同左 | +| stream | both ends | only T2 (no shared memory); knob 0 prints `Refuse{AdoptTierOnStream, "T0"}` | `Refuse{AdoptTierOnStream, "T1"}`, T2 | +| shared segment | client | requests T0 in `Hello`'s `LinkTerms.adoptTier` (0; `kAdoptAskT0Default` when unset); whether T0 really runs is read from `kCapAdoptT0` at the first `map_persistent` (`ClientSession::AdoptT0`) | `Refuse{AdoptTierClosed, "T1"}`, requests T2 | +| shared segment | server | does not look at its own knob: it follows the client's request, approving it at the first native bind (`ServerSession::SettleAdoptT0AtBind`, with the later `CapsSnapshot` carrying `kCapAdoptT0`) or stating the reason by name | same as left | -T2 路径上的使用时检查 `Client::AdoptTierIsEmulate` 读回结算结果:已结算的会话照常走 T2;knob 0 / 1 下没有任何握手结算过的 `map_persistent`(无会话的调用方)具名中止为 `Fatal{UnimplementedAdoptTier}`,不静默当成 T2。 +The use-time check on the T2 path, `Client::AdoptTierIsEmulate`, reads back the settlement result: a settled session takes T2 as usual; under knob 0 / 1, a `map_persistent` that no handshake settled (a caller with no session) aborts by name as `Fatal{UnimplementedAdoptTier}`, rather than silently counting as T2. -## 13. 回读、roundtrip 清单与验证 +## 13. Readback, the roundtrip list and verification -### 13.1 稳态零 roundtrip 与不可避免的阻塞点 +### 13.1 Steady-state zero roundtrips and the unavoidable blocking points -- 零 roundtrip:全部 draw / clear / blit / copy / dispatch / XFB / bind / CSO / `set_*` / 上传 / `present`;全部 caps 站点;`glGetError` / `glFinish` / `glFlush`;fence 与 query 的创建和非阻塞轮询;`eglSwapBuffers`;restart / multi-draw。 -- 不可避免(罕见):握手;surface 生命周期;`glReadPixels` 到客户内存;GPU-write pending 的 buffer 首次 CPU 读;带超时的 sync / query 结果;`glBufferStorage` 的 ack;纹理拉取;ring / stage 耗尽与 present credit。 -- 跨机上每条 `kWaitReply`(`ResourceCreate`、`SetTextureParams`、纹理 `ResourceSubData`)都是一个 RTT:逐帧次数是 P6.5 必测数,减少它是 P9 / P10 的活。 +- Zero roundtrips: all draw / clear / blit / copy / dispatch / XFB / bind / CSO / `set_*` / upload / `present`; all caps sites; `glGetError` / `glFinish` / `glFlush`; fence and query creation and non-blocking polling; `eglSwapBuffers`; restart / multi-draw. +- Unavoidable (rare): the handshake; the surface lifetime; `glReadPixels` into client memory; the first CPU read of a buffer with GPU writes pending; sync / query results with a timeout; the `glBufferStorage` ack; texture pulls; ring / stage exhaustion and present credit. +- Across machines every `kWaitReply` (`ResourceCreate`, `SetTextureParams`, a texture `ResourceSubData`) is one RTT: the per-frame count is a mandatory measurement for P6.5, and reducing it is P9 / P10 work. -#### 13.1.1 kWaitReply 行的逐记录豁免 +#### 13.1.1 Per-record exemptions from the kWaitReply row -`kWaitReply` 是行级属性;一条记录是否真的阻塞由逐记录谓词决定,route 与 wire emit 表读同一个函数,避免一边等另一边没要的回包。因此上面第三条所列的纹理 `ResourceSubData` 在 wire 臂上已不逐条付 RTT。 -- `resource_subdata`(`MGPipeSubDataWantsItsReply`):buffer 那半的 Bool 无人读,不等。wire 臂上纹理那半也不等:纹理记录只在 server 消费纹理族时才发(caps 镜像里的 consumer 位,与 applier 的接受检查读同一事实),所以 applier 唯一的合法拒绝"无 consumer"落不到这条记录上;其余拒绝(如目标不是纹理、无纹素或无字节、未知句柄)都是 bug,server 侧会 trip wire 报告或计数具名。client 自己取消的记录(device lost、stage 耗尽)仍答"未接受",level 留脏重试。等待由此从每条记录移到 `SEG_STAGE` 窗口回收,与窗口成正比而不是与调用数成正比(实测见 `MEASUREMENTS.md`「纹理上传的等待粒度」一条)。 -- `resource_respecify`(`MGPipeResourceRespecifyWantsItsReply`):wire 臂上 buffer 那半不等;纹理那半等到对象的 create 被接受(`MGPipeHandleIsPublished`),之后 acceptance 已是 client 知道的事实,首次使用时付一次阻塞的 create;create 被拒则闩不置位,后续照常等真答案,代价是吞吐而不是静默。 -- monolith 下答案在调用线程上直接返回、没有代价,谓词保持原答案(纹理那半照收)。 +`kWaitReply` is a row-level property; whether a record actually blocks is decided by a per-record predicate, and the route and the wire emit table read the same function, so one side does not wait for a reply the other never asked for. That is why the texture `ResourceSubData` listed in the third point above no longer pays an RTT per record on the wire arm. +- `resource_subdata` (`MGPipeSubDataWantsItsReply`): nobody reads the Bool in the buffer half, so it does not wait. On the wire arm the texture half does not wait either: a texture record is sent only when the server consumes the texture family (the consumer bit in the caps mirror, reading the same fact as the applier's acceptance check), so the applier's only legitimate refusal, "no consumer", cannot fall on this record; the other refusals (such as the target not being a texture, no texels or no bytes, an unknown handle) are bugs, and the server side trips a wire report or counts them by name. A record the client itself cancels (device lost, stage exhaustion) still answers "not accepted", and the level stays dirty for a retry. The wait thus moves from each record to the `SEG_STAGE` window reclamation, proportional to the window instead of to the number of calls (measured under "the wait granularity of texture uploads" in `MEASUREMENTS.md`). +- `resource_respecify` (`MGPipeResourceRespecifyWantsItsReply`): on the wire arm the buffer half does not wait; the texture half waits until the object's create has been accepted (`MGPipeHandleIsPublished`), after which acceptance is already a fact the client knows, so first use pays one blocking create; if the create is refused the latch is not set, and later calls wait for the real answer as usual, at the cost of throughput rather than silence. +- Under the monolith the answer returns directly on the calling thread at no cost, so the predicate keeps its original answer (the texture half still takes it). -#### 13.1.2 client 侧保守 GPU 写集合 +#### 13.1.2 The client-side conservative GPU write set -`BufferObject::SyncGpuWrites` 在应用线程上、于 `glMapBuffer` / `glGetBufferSubData` 时回答"GPU 是否可能写过这块 buffer"。后端的标记点在 server 侧,逐次去问是稳态禁止的 roundtrip,所以 client 在每条 draw / dispatch 记录发出之前,从自己持有的绑定构建这个集合(`MG_Impl/Pipe/Verb/GpuWriteSet.h`)。 +At `glMapBuffer` / `glGetBufferSubData` on the application thread, `BufferObject::SyncGpuWrites` answers "may the GPU have written this buffer". The backend's mark points are on the server side, and asking each time is a roundtrip forbidden in the steady state, so the client builds this set from the bindings it holds before each draw / dispatch record is sent (`MG_Impl/Pipe/Verb/GpuWriteSet.h`). -- 宁多勿少:多标一次的代价是一次回读,漏标则静默读到陈旧 shadow。每个生产者有计数器(`ProducerMarkCount`),单元用例断言它确实触发。 -- 前四个生产者对应后端标记点:SSBO 绑定点、atomic counter 绑定点(标全部 touched 点,比后端宽)、`Access != GL_READ_ONLY` 的 image buffer texture、XFB 捕获目标。后端故意窄的两处照搬:只读 image 绑定不标;image 遍历在 draw 准备时做,不在 `glBindImageTexture` 时做。 -- 后端没有的两个生产者:读进 pack PBO 的 `glReadPixels` 发出即返回、只做标记,拷贝推迟到第一次真要读时;传输下 `glEndTransformFeedback` 不再无界等 fence,只标记捕获目标(monolith 仍等)。 -- 收窄尚未实现:`MGPipeClientOnGpuWritten` 只接受一个整 buffer 范围;零个范围留给将来的"已完全收窄",不能当作整块已写。 -- 不覆盖后端自己的 scratch buffer(Espryt 的转换顶点流与 primitive-restart 替换 buffer、Magma 的 UBO ring):后端那边同样没有 `MarkGpuWritten`,是两边共有的洞。 +- Better too many than too few: marking once too often costs one readback, while a missing mark silently reads a stale shadow. Each producer has a counter (`ProducerMarkCount`), and a unit test asserts that it really fires. +- The first four producers correspond to backend mark points: SSBO binding points, atomic counter binding points (marking every touched point, wider than the backend), image buffer textures with `Access != GL_READ_ONLY`, and XFB capture targets. Two places where the backend is deliberately narrow are copied as they are: a read-only image binding is not marked; the image walk happens at draw preparation, not at `glBindImageTexture`. +- Two producers the backend does not have: a `glReadPixels` reading into a pack PBO returns as soon as it is issued, only marking, and the copy is deferred to the first time a read really happens; under transport `glEndTransformFeedback` no longer waits for a fence without bound, only marking the capture targets (the monolith still waits). +- Narrowing is not implemented yet: `MGPipeClientOnGpuWritten` accepts only one whole-buffer range; zero ranges is reserved for a future "fully narrowed" and must not be taken as the whole buffer written. +- It does not cover the backend's own scratch buffers (Espryt's conversion vertex stream and primitive-restart replacement buffer, Magma's UBO ring): the backend side has no `MarkGpuWritten` for them either, so it is a hole the two sides share. -#### 13.1.3 glReadPixels:线上只有矩形,pack 状态留在 client +#### 13.1.3 glReadPixels: only the rectangle goes on the wire, the pack state stays on the client -`read_pixels` 记录带的是矩形而不是布局:`MGPReadbackInfo::DstSize` 是紧凑的 `w*h*bytesPerPixel`,server 用中性 pack 状态读进这段紧凑行(就是 reply payload),client——唯一持有应用 pack 状态的一侧——再按应用的 `GL_PACK_*` 把各行散射到应用指针,行间空隙不写。若 `DstSize` 取打包后的尺寸,server 按它分配、后端又按实时 pack 状态写,就会越界(4x3 RGBA8、`PACK_ROW_LENGTH=8`、`SKIP_ROWS=1`、`SKIP_PIXELS=2`:分配 80 B,驱动写到第 120 B)。规则只关乎布局,深度与深度模板读同样适用。 -- 紧凑答案大于一个 reply slot(`LinkTerms.maxReplyBytes`)时切的是读,不是 reply:一行放得下就切成 `floor(maxReplyBytes / rowBytes)` 行的整宽行带,否则把每行切成 `floor(maxReplyBytes / bpp)` 像素的列段。每段是一条普通 `read_pixels` 记录,带自己的框与紧凑 `DstSize`,各自按 pack 状态散射;段按行主序恰好覆盖矩形一次,且在紧凑布局里连续,中性 pack 的快路径因此仍可直接读进应用指针(`PlanReadbackBands` / `ForEachReadbackBand`)。 -- 只有连一个像素都放不进 reply(含没有 reply 池的链路)时,client 才在发射前具名拒绝为 `Fatal{ReplyTooLarge}`:像素不能拆得比自身更小。 +The `read_pixels` record carries the rectangle, not the layout: `MGPReadbackInfo::DstSize` is the tight `w*h*bytesPerPixel`, and the server reads into these tight rows with a neutral pack state (that is the reply payload), after which the client—the only side that holds the application pack state—scatters the rows to the application pointer according to the application's `GL_PACK_*`, not writing the gaps between rows. If `DstSize` were the packed size, the server would allocate by it while the backend writes by the live pack state, and the write would overflow (4x3 RGBA8, `PACK_ROW_LENGTH=8`, `SKIP_ROWS=1`, `SKIP_PIXELS=2`: 80 B allocated, the driver writes up to byte 120). The rule is about layout only, and the same applies to depth and depth-stencil reads. +- When the tight answer is larger than one reply slot (`LinkTerms.maxReplyBytes`), what is split is the read, not the reply: if one row fits, split into full-width row bands of `floor(maxReplyBytes / rowBytes)` rows; otherwise split each row into column runs of `floor(maxReplyBytes / bpp)` pixels. Each band is an ordinary `read_pixels` record with its own box and tight `DstSize`, each scattered according to the pack state; the bands cover the rectangle exactly once in row-major order and are contiguous in the tight layout, so the neutral-pack fast path can still read straight into the application pointer (`PlanReadbackBands` / `ForEachReadbackBand`). +- Only when not even one pixel fits in a reply (including a link with no reply pool) does the client refuse by name as `Fatal{ReplyTooLarge}` before emitting: a pixel cannot be split smaller than itself. -### 13.2 五部分验证门(取代 monolith 的字节一致门) +### 13.2 The five-part verification gate (replacing the monolith's byte-identity gate) -1. **接口纯度**:A 门 include 图(`scripts/check_include_closure.py`)、B 门 server 镜像不引用 `MG_State::GLState` 与 glslang(P6 的 a6 实测 server 仍链 `MG_Impl`,由 `scripts/link_ratchet.py` 的下行棘轮追踪;P13 把 172 条降到 27 条具名债务、`# P13` 注解清零并由脚本拒绝回潮,W7 的 `MobileGL_server_linkcheck` 把它变成真链接)、C 门 `MG_Backend` 里零 `pGLContext`;外加"每个后端 memo 键都是 `{slot, gen}`"(`HandleRecycleScenario`)。 -2. **语义影子比对** `MOBILEGL_PIPE_VERIFY=1`:tracker 再用 `SnapshotFromGLContext()` 填一份 `PipeInputs`,G4 逐字段每 draw 比对,打印第一个分歧;verify 构建永不出货,活过 P13。 -3. **行为 A/B**:trace 语料在 monolith / split 下 SSIM ≥ 0.99(P13 前还有 monolith-pull / monolith-push 两臂);测试名只增不删(G14),skip 普查守住「跳过」与名集合;CTS 逐后端 0.5 pp 内;上传形状金标与 recorder 金标(§13.3)。 -4. **性能**:Redmi `2f7cbe2e` reboot-clean、同热窗口配对 A/B,指标是**逐线程 CPU 时间**;**只记录、不设门**(用户 2026-09-08)。P13 之后的性能轮以 `dev` 构建为基线(用户 2026-10-07)。 -5. **覆盖 + poison + 句柄纪律**:G6 0 UNMAPPED、dirty-surface 0 未映射、G8 归属完备、逐 verb poison、G7、残余块棘轮。 +1. **Interface purity**: gate A checks the include graph (`scripts/check_include_closure.py`), gate B that the server image references neither `MG_State::GLState` nor glslang (P6's a6 measured that the server still links `MG_Impl`, tracked by the downward ratchet in `scripts/link_ratchet.py`; P13 brings 172 down to 27 named debts, zeroes the `# P13` annotations, and a script refuses regressions, while W7's `MobileGL_server_linkcheck` turns it into a real link), and gate C zero `pGLContext` in `MG_Backend`; plus "every backend memo key is `{slot, gen}`" (`HandleRecycleScenario`). +2. **Semantic shadow comparison** `MOBILEGL_PIPE_VERIFY=1`: the tracker fills a second `PipeInputs` with `SnapshotFromGLContext()`, and G4 compares field by field at every draw, printing the first divergence; verify builds never ship and survive P13. +3. **Behavior A/B**: the trace corpus has SSIM ≥ 0.99 under monolith / split (before P13 there were also the monolith-pull / monolith-push arms); test names only grow, never shrink (G14), and the skip census guards "skips" and the name set; CTS is within 0.5 pp per backend; the upload-shape goldens and the recorder goldens (§13.3). +4. **Performance**: Redmi `2f7cbe2e`, reboot-clean, paired A/B in the same thermal window, with **per-thread CPU time** as the metric; **recorded only, no gate** (user, 2026-09-08). Performance rounds after P13 use the `dev` build as the baseline (user, 2026-10-07). +5. **Coverage + poison + handle discipline**: G6 0 UNMAPPED, dirty-surface 0 unmapped, G8 ownership complete, per-verb poison, G7, the residual-block ratchet. -幸存的字节级等式:`MOBILEGL_BUILD_DISAGGREGATED=OFF` 时库里零 `MG_Remote` 符号(P13 起它就是出货库)。**G1**(pull 构建的符号集与 `.text` 对基线恒等)随 pull 构建在 P13 退役,由零 `MG_Remote` 符号、skip 普查与 recorder 金标接班。**每个门必须能因它存在的理由变红**(R-16):带阴性对照并真跑过一次红;公共 GL 看不见的改白盒断言;拒绝普查逐用例读私有日志(`ctest -V` 是假零)。 +The byte-level identity that survives: with `MOBILEGL_BUILD_DISAGGREGATED=OFF` the library has zero `MG_Remote` symbols (since P13 it is the shipping library). **G1** (the pull build's symbol set and `.text` identical to the baseline) retires with the pull build in P13, and zero `MG_Remote` symbols, the skip census and the recorder goldens take over. **Every gate must be able to go red for the reason it exists** (R-16): it has a negative control and has really run red once; a change the public GL cannot see gets a white-box assertion; the refusal census reads the private log per case (`ctest -V` is a false zero). -### 13.3 长期语义门:MGPipe recorder(P13) +### 13.3 The long-term semantic gate: the MGPipe recorder (P13) -`MG_Test/Pipe/RecorderGoldenTest.cpp`(P13 W8):记录器装在记录离开 client 的每一扇门上——两张 MGPipe 接口表与路由 escape(全部状态 / 对象记录)、verb 会话(全部 verb 记录)。固定的 GL 调用序列(缓冲 + VAO + 采样纹理 + program + 四种 draw;两张纹理的 framebuffer + 两种 clear + blit + mipmap)逐条录下,规范化只做一件事:指向调用方内存的 `MGPBlobRef` / `MGHostSpan` 地址清零、长度保留、所指字节入哈希。金标是一行一条记录(序号、调用名、字节数、哈希),在 `MG_Test/Pipe/goldens/recorder/`;`MOBILEGL_RECORDER_GOLDEN_WRITE=1` 才重写,且重写的那次必红。阴性对照:改一条 verb 记录的一个字段必须在那条红;改一个 GL 输入必须在资源记录处红。两种库形态(有无 `MG_Remote`)对同一金标——它第一次跑就发现无传输库的单进程不发 `set_context_values`(已修)以及 `RenderStateParameters` 的填充字节未清零(会让内容寻址的 CSO 在两个状态相同的 context 间不复用,已修)。它只覆盖推送内容,不覆盖后端对它的解释(开放问题 12)。 +`MG_Test/Pipe/RecorderGoldenTest.cpp` (P13 W8): the recorder sits at every gate through which a record leaves the client—the two MGPipe interface tables and the route escapes (all state / object records), and the verb session (all verb records). A fixed GL call sequence (a buffer + a VAO + a sampled texture + a program + four kinds of draw; a framebuffer with two textures + two kinds of clear + blit + mipmap) is recorded record by record, and normalization does exactly one thing: the addresses of `MGPBlobRef` / `MGHostSpan` pointing at caller memory are zeroed, the lengths kept, and the bytes they point at hashed. A golden is one line per record (ordinal, call name, byte count, hash), under `MG_Test/Pipe/goldens/recorder/`; it is rewritten only with `MOBILEGL_RECORDER_GOLDEN_WRITE=1`, and the rewriting run must go red. Negative controls: changing one field of a verb record must go red on that record; changing one GL input must go red at the resource record. Both library shapes (with and without `MG_Remote`) compare against the same golden—on its first run it found that the monolith library without a transport did not send `set_context_values` (fixed), and that `RenderStateParameters`'s padding bytes were not zeroed (which would stop a content-addressed CSO from being reused between two contexts with the same state; fixed). It covers only the pushed content, not the backend's interpretation of it (open question 12). diff --git a/docs/Disaggregated/design/08-runtime-and-platform.md b/docs/Disaggregated/design/08-runtime-and-platform.md index 40f53183..e6bb4640 100644 --- a/docs/Disaggregated/design/08-runtime-and-platform.md +++ b/docs/Disaggregated/design/08-runtime-and-platform.md @@ -1,87 +1,87 @@ -# 帧节奏、进程、EGL 与平台(原 ARCHITECTURE §14–§15) +# Frame pacing, processes, EGL and platform (formerly ARCHITECTURE §14–§15) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design points and the index of all chapters are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; an `ARCHITECTURE.md §N` in a code comment is found by its number here. -## 14. Present、线程与帧节奏 +## 14. Present, threads and frame pacing -- `eglSwapBuffers` → `present{frameSerial}` → publish + 敲门铃 → 返回,除非超出 credit;**`present` 与 `eglSwapBuffers` 严格 1:1**(后端的帧边界排空只在 `Present` 内发生)。 -- `MOBILEGL_IPC_PRESENT_CREDIT` 默认 1(range 1..8):credit 是 run-ahead 唯一的稳态背压,`FrameSerial` 由 client 铸造、1 起算,server 在 `Present()` 返回后归还 credit;等待发生在**编码之前**。credit > 1 从未量过(P10)。 -- 预算(~850 draw/帧):`SEG_CMD` ~70 KB/帧,`SEG_STAGE` ~1 MB/帧;跨机时这 ~1 MB/帧对着的是 Wi-Fi。 -- 线程:client v1 不加线程,编码在 GL 线程直接写 ring;server 有 io 线程与**终身持有原生 context** 的 `mgl-srv-apply`。全库无有效亲和性控制(Redmi 内核忽略 app 线程的 `sched_setaffinity`)。 -- 拆机顺序:publish + server 排空 → 停 apply 线程 → 关传输 → client 排空编译池 → `MobileGL::Destroy()`(落地形状见 §17)。 +- `eglSwapBuffers` → `present{frameSerial}` → publish + ring the doorbell → return, unless the credit is exceeded; **`present` and `eglSwapBuffers` are strictly 1:1** (the backend's frame-boundary drain happens only inside `Present`). +- `MOBILEGL_IPC_PRESENT_CREDIT` defaults to 1 (range 1..8): the credit is the only steady-state backpressure for run-ahead, `FrameSerial` is minted by the client and starts at 1, and the server returns the credit after `Present()` returns; the wait happens **before encoding**. credit > 1 has never been measured (P10). +- Budget (~850 draws/frame): `SEG_CMD` ~70 KB/frame, `SEG_STAGE` ~1 MB/frame; across machines that ~1 MB/frame faces Wi-Fi. +- Threads: client v1 adds no thread, and encoding writes the ring directly on the GL thread; the server has an io thread and `mgl-srv-apply`, which **holds the native context for life**. The whole library has no effective affinity control (the Redmi kernel ignores `sched_setaffinity` for app threads). +- Teardown order: publish + server drain → stop the apply thread → close the transport → the client drains the compile pool → `MobileGL::Destroy()` (the landed shape is in §17). -### 14.1 apply 线程的亲和与自旋(`auto`) +### 14.1 Affinity and spin of the apply thread (`auto`) -`MOBILEGL_IPC_SERVER_AFFINITY=auto`(缺省)按会话对端(`Hello` 的 `DialMode`)与数据面选择 apply 线程的亲和与 park 前自旋(`MG_Remote/Server/ApplyThreadPolicy.h`,纯函数):同进程、fork 出的、拨入但走 stream 的对端 → 全部大核与 `MOBILEGL_IPC_SPIN_US`;拨入且走共享段的对端 → 一个核(`ReservedApplyCore`:多个 prime 核时取最低的;只有一个 prime 核时取另一个大核;否则不钉,绝不给唯一的 prime 核)与 `kConnectedPeerSpinUs`(除非显式设了 `MOBILEGL_IPC_SPIN_US`)。显式掩码或 `off` 对任何对端优先。 -- 拨入的共享段 client 直接写 apply 线程自旋的那条环,两边又落在同两颗 prime 核上:Redmi 上共享段 23–26 fps、TCP 45–54,手工分开后 118。stream 数据面由 io 线程喂 apply 线程,apply 不在 client 的写上自旋(apply CPU 7.9 ms/帧,共享段 26.8),所以维持全部大核。 -- 取最低而非最高的 prime 核:调度器把前台应用的热 GL 线程放在最高的 prime 核(44 次采样 43 次在 cpu7);apply 线程钉在那里 6.5 fps,钉在最低的 120 fps。 -- 短自旋保留:立即 park(0)在所有量过的格子里都更慢(helper 路径 120 → 74 fps,shell 27 → 17)。 -- 经 `ExternalClientHelper` 启动的 client 也被挡在保留核之外:supervisor 启动时公布该核(`ReservedApplyCoreForConfig`),broker 交给 helper;操作员给了掩码或 `off` 时不保留任何核。 +`MOBILEGL_IPC_SERVER_AFFINITY=auto` (the default) chooses the apply thread's affinity and pre-park spin from the session peer (`Hello`'s `DialMode`) and the data plane (`MG_Remote/Server/ApplyThreadPolicy.h`, pure functions): a same-process peer, a forked peer, or a dialed-in peer on stream → all big cores and `MOBILEGL_IPC_SPIN_US`; a dialed-in peer on a shared segment → one core (`ReservedApplyCore`: the lowest when there are several prime cores; another big core when there is only one prime core; otherwise no pinning, and never the only prime core) and `kConnectedPeerSpinUs` (unless `MOBILEGL_IPC_SPIN_US` is set explicitly). An explicit mask or `off` takes precedence for any peer. +- A dialed-in shared-segment client writes directly to the ring the apply thread spins on, and the two land on the same two prime cores: on the Redmi the shared segment gives 23–26 fps and TCP 45–54, and 118 after separating them by hand. On the stream data plane the io thread feeds the apply thread, and apply does not spin on the client's writes (apply CPU 7.9 ms/frame, versus 26.8 on the shared segment), so all big cores are kept. +- Taking the lowest rather than the highest prime core: the scheduler puts the foreground app's hot GL thread on the highest prime core (43 of 44 samples on cpu7); pinning the apply thread there gives 6.5 fps, while pinning it to the lowest gives 120 fps. +- The short spin is kept: parking immediately (0) is slower in every measured cell (the helper path 120 → 74 fps, the shell 27 → 17). +- A client started through `ExternalClientHelper` is kept off the reserved core too: the supervisor announces the core at startup (`ReservedApplyCoreForConfig`) and the broker passes it to the helper; when the operator gives a mask or `off`, no core is reserved. -## 15. 进程、EGL 与平台(P6 / P6.5 / P12) +## 15. Processes, EGL and platform (P6 / P6.5 / P12) -### 15.1 启动与握手 +### 15.1 Startup and handshake -- 端点:`fork`(`socketpair` + `fork`/`execve`,fd 3 = socket;server 由 `MOBILEGL_IPC_SERVER_PATH` 或 `dladdr` 同目录的 `libMobileGLServer.so` 定位)、`unix:`、`tcp://host:port`。设备侧 supervisor `mobilegl_server_main --serve`:listen → 认证 → 每会话 fork 一个子进程(或进程内线程,P12),同时只服务一个会话,第二个连接 `Refuse{Busy}`。 -- server 进程里 `Transport` 读作 `Spawn`,**不强制 monolith**(两百多处 `Transport != Monolith` 判断靠它选 server 臂;`CONTRACT-P6.md` §3.1 修订了原"子进程强制 monolith"的规则)。防无界 fork 链靠不继承的 `Dial == No`(`MOBILEGL_IPC_DIAL=no`),spawn 时构造的 envp 剔除 `MOBILEGL_TRANSPORT` 与 `MOBILEGL_IPC_*` 作第二道独立保险;server 主程序自设 `MOBILEGL_IPC_ROLE=server`。 -- `Hello`(abi、后端类型、指纹、配置、令牌、`LinkTerms` 请求)→ `Welcome`(server 陈述的尺寸、段 / aux 名、`dataNonce`、真实 pid)或 `Refuse{code, detail, 对端值}`;握手路径零 abort。非 loopback 监听必须有令牌(≥16 字节、常量时间比较、数据面按 `dataNonce` 绑定到已认证的控制连接、fork 前认证;Ph,OQ-21 裁定不做 TLS)。 -- TCP keepalive / 心跳失败**由传输层报告为挂断**,进 device-lost 闩;"闩绝不取自 apply 超时"不因此松动。冷启动期 server 发 `SurfaceProgress`,client 预算这段沉默(控制修订 2)。 +- Endpoints: `fork` (`socketpair` + `fork`/`execve`, fd 3 = socket; the server is located by `MOBILEGL_IPC_SERVER_PATH` or by `libMobileGLServer.so` in the same directory via `dladdr`), `unix:`, `tcp://host:port`. The device-side supervisor is `mobilegl_server_main --serve`: listen → authenticate → fork one child process per session (or an in-process thread, P12), serving one session at a time, with a second connection getting `Refuse{Busy}`. +- Inside the server process `Transport` reads as `Spawn`, and **this does not force the monolith** (the two hundred-odd `Transport != Monolith` checks rely on it to pick the server arm; `CONTRACT-P6.md` §3.1 revises the original "a child process forces the monolith" rule). An unbounded fork chain is prevented by the non-inherited `Dial == No` (`MOBILEGL_IPC_DIAL=no`), and the envp built at spawn strips `MOBILEGL_TRANSPORT` and `MOBILEGL_IPC_*` as a second, independent safeguard; the server main program sets `MOBILEGL_IPC_ROLE=server` itself. +- `Hello` (abi, backend type, fingerprints, configuration, token, `LinkTerms` request) → `Welcome` (the sizes the server states, segment / aux names, `dataNonce`, the real pid) or `Refuse{code, detail, peer value}`; the handshake path has zero aborts. A non-loopback listen requires a token (≥16 bytes, constant-time comparison, the data plane bound to the authenticated control connection by `dataNonce`, authentication before fork; Ph, with OQ-21 ruling out TLS). +- A TCP keepalive / heartbeat failure **is reported by the transport as a hang-up** and enters the device-lost latch; "the latch is never taken from an apply timeout" is not loosened by this. During cold start the server sends `SurfaceProgress`, and the client budgets that silence (control revision 2). -#### 15.1.1 TCP supervisor 的预认证 +#### 15.1.1 Pre-authentication in the TCP supervisor -TCP `--serve` 的 supervisor(`ServerMain.cpp` 的 `TcpSupervisor`,判定部分在 `PreAuthGate.h`)先认证、再把会话交出去(fork 子进程,或进程内线程);未认证的对端最多占一个有界的 pending 槽: +The supervisor of TCP `--serve` (`TcpSupervisor` in `ServerMain.cpp`, with the decision part in `PreAuthGate.h`) authenticates first and only then hands the session over (a forked child, or an in-process thread); an unauthenticated peer holds at most one bounded pending slot: -- 新连接在首帧完整之前是 pending。supervisor 在一个 poll 循环里同时从所有 pending 连接非阻塞地读,任何未认证对端都拖不住别人;只读到首帧末尾,之后的字节属于会话。 -- 每个 pending 连接有 `MOBILEGL_IPC_PREAUTH_MS`(默认 2000)读完首帧,同时最多 `MOBILEGL_IPC_PREAUTH_MAX`(默认 8)个。队列按地址共享:满时新连接挤掉占槽最多的地址最老的那个;它自己的地址已占同样多时,被拒 `Busy` 的是它。 -- Hello 在 supervisor 里认证、令牌先于指纹:未认证的对端只收到 `Refuse{Authentication}`,得不到本构建的 wire / build 指纹。只为已认证的 Hello 交出会话,并把这一帧交给会话。 -- 失败(令牌错、首帧畸形、超时、静默占槽超过 `kPreAuthProbeGraceMs` 后关闭或被挤掉)记在对端地址上;满 `MOBILEGL_IPC_AUTH_BACKOFF_AFTER`(默认 5,0 = 关)次后该地址在 accept 时、读任何字节之前即被拒,窗口自 `MOBILEGL_IPC_AUTH_BACKOFF_MS`(默认 1000)起逐次翻倍、上限一分钟;该地址认证成功一次即清零。宽限期内无字节就关闭的端口探测、指向无活会话的 DataBind、退避本身发出的拒绝都不算失败。 -- DataBind 经 hand-off 连同 nonce 转给活会话(会话比较 nonce);没有活会话时由 supervisor 具名拒绝。已认证的第二个 Hello 收到 `Busy`。 -- 判定部分不含 I/O(`MG_Remote/Server/PreAuthGate.h`),由 `PreAuthGateTest` 覆盖;早于 `kAuthBackoffForgetMs` 的失败不再计入退避。 +- A new connection is pending until its first frame is complete. The supervisor reads from all pending connections non-blocking in a single poll loop, so no unauthenticated peer can hold up the others; it reads only up to the end of the first frame, and the bytes after that belong to the session. +- Each pending connection has `MOBILEGL_IPC_PREAUTH_MS` (default 2000) to finish the first frame, and there are at most `MOBILEGL_IPC_PREAUTH_MAX` (default 8) at a time. The queue is shared by address: when it is full, a new connection evicts the oldest one of the address holding the most slots; if its own address already holds as many, it is the one refused with `Busy`. +- Hello is authenticated in the supervisor, token before fingerprints: an unauthenticated peer only receives `Refuse{Authentication}` and never gets this build's wire / build fingerprints. The session is handed over only for an authenticated Hello, and that frame is passed to the session. +- A failure (wrong token, malformed first frame, timeout, a silent slot-holder closed after `kPreAuthProbeGraceMs`, or being evicted) is recorded against the peer address; after `MOBILEGL_IPC_AUTH_BACKOFF_AFTER` (default 5, 0 = off) failures that address is refused at accept time, before any byte is read, with the window doubling from `MOBILEGL_IPC_AUTH_BACKOFF_MS` (default 1000) up to one minute; one successful authentication of that address clears it. A port probe that closes without sending a byte within the grace period, a DataBind aimed at no live session, and a refusal issued by the backoff itself do not count as failures. +- DataBind is handed off with the nonce to the live session (which compares the nonce); with no live session the supervisor refuses by name. A second authenticated Hello receives `Busy`. +- The decision part contains no I/O (`MG_Remote/Server/PreAuthGate.h`) and is covered by `PreAuthGateTest`; failures older than `kAuthBackoffForgetMs` no longer count toward the backoff. ### 15.2 Android -- 交付链(spike A 已证):APK 唯一可 exec 的位置是 `lib//`,server 以 `add_executable` + `lib*.so` 命名构建;从 `untrusted_app` 进程 `fork`+`execve` 同域、零 avc denial;`posix_spawn` 在 minSdk 26 不可用。一份共享库两个角色(stub `dlopen` + `dlsym("mobilegl_server_main")`)。 -- 离屏 server:前台 `MobileGLServerService`(`:mglsrv`),从 `nativeLibraryDir` exec,fork-per-session,EGL 是 pbuffer / surfaceless。 -- **上屏 server(P12 子集)**:窗口归 **server 自己**(client 的窗口不跨进程)。`MobileGLDisplayActivity`(`:mglwin`)持全屏 SurfaceView,在自己的进程里用一个线程跑 TCP server(会话串行、会话间重置闩、后端按进程钉住);`ServerDisplay` 以 acquire / release / 几何三个钩子持有窗口,apply 线程以**租约**使用它。client 设 `MOBILEGL_IPC_SURFACE=server` 后**无头**:`eglCreateWindowSurface(NULL)` 发一帧 `WindowKind::ServerOwned`(控制修订 3),不发 `SetWindowHandle`,尺寸由 reply 带回,resize 变成对 server 窗口的几何请求;client 没给 `EGL_WIDTH/HEIGHT`(SDL)时取 native window 的大小作请求,server 把窗口缓冲固定成它并等比留黑边(不然横屏游戏在竖屏窗口里被裁)。FCL 只能接外部 server(自带 spawn 会把窗口指针发过来,被 Rule H 拒),且要开版本设置「游戏退到后台时不暂停」,否则 FCL 一退后台游戏就暂停(见 git 历史)。一台设备同一时刻一个 server;一个会话一种表面模式(`SurfaceModeMismatch`);无显示的 server 对 ServerOwned 具名拒绝(`NoServerDisplay`)。 -- 失窗:`surfaceDestroyed` 有界(3 s)阻塞,直到 apply 线程(批内每条记录前也检查)放掉后端表面并以 `Fatal{ServerWindowLost}` 闩住会话;server 继续监听。进程内会话结束时手动做进程退出本来白给的清理(Espryt twin 与单元影子、swap interval、Magma renderer)。 -- `HeadlessGL` 的 fork 预检会产生孤儿 server:server 的 EOF 检测即时且无条件退出。 +- Delivery chain (proven in spike A): the only executable location in an APK is `lib//`, and the server is built with `add_executable` + a `lib*.so` name; `fork`+`execve` from an `untrusted_app` process stays in the same domain with zero avc denials; `posix_spawn` is unavailable at minSdk 26. One shared library, two roles (the stub does `dlopen` + `dlsym("mobilegl_server_main")`). +- Offscreen server: the foreground `MobileGLServerService` (`:mglsrv`), exec'd from `nativeLibraryDir`, fork-per-session, with pbuffer / surfaceless EGL. +- **On-screen server (P12 subset)**: the window belongs to **the server itself** (the client's window does not cross processes). `MobileGLDisplayActivity` (`:mglwin`) holds a full-screen SurfaceView and runs a TCP server on one thread in its own process (sessions serial, the latch reset between sessions, the backend pinned per process); `ServerDisplay` holds the window through three hooks—acquire / release / geometry—and the apply thread uses it under a **lease**. After the client sets `MOBILEGL_IPC_SURFACE=server` it is **headless**: `eglCreateWindowSurface(NULL)` sends one `WindowKind::ServerOwned` frame (control revision 3) and does not send `SetWindowHandle`, the size comes back in the reply, and a resize becomes a geometry request to the server window; when the client gives no `EGL_WIDTH/HEIGHT` (SDL), the native window size is taken as the request, and the server fixes the window buffer to it and letterboxes it with black bars (otherwise a landscape game would be cropped in a portrait window). FCL can only attach to an external server (its own spawn would send the window pointer over, which Rule H refuses), and it needs the version setting "do not pause the game when it goes to the background", otherwise the game pauses as soon as FCL goes to the background (see git history). One server per device at a time; one surface mode per session (`SurfaceModeMismatch`); a server with no display refuses ServerOwned by name (`NoServerDisplay`). +- Window loss: `surfaceDestroyed` blocks with a bound (3 s) until the apply thread (which also checks before every record in a batch) drops the backend surface and latches the session with `Fatal{ServerWindowLost}`; the server keeps listening. When an in-process session ends, the cleanup that a process exit would give for free is done by hand (Espryt twins and unit shadows, swap interval, the Magma renderer). +- `HeadlessGL`'s fork pre-check produces orphan servers: the server's EOF detection exits immediately and unconditionally. -### 15.3 Linux / Windows / 崩溃 +### 15.3 Linux / Windows / crashes -- Linux / WSL / CI 永不开窗(`EGL_PLATFORM=surfaceless`);Wayland 不支持。Windows / 桌面 client 在 TCP 终局下是真实形态(Windows 是第二批,开放问题 22);macOS 不拆分;Windows 机器不是正确性门。 -- server 死:client 读到挂断 → **device-lost 闩**(GL 调用 no-op、`eglSwapBuffers` 返回 `EGL_CONTEXT_LOST`、reset status `GL_UNKNOWN_CONTEXT_RESET`);`Session::Fail` 漏斗向对端发 `SessionFault` 帧命名家族(`FatalFamilies.def`)。闩之前创建的 context 永久丢失(`eglMakeCurrent` / `eglSwapBuffers` 返回 `EGL_CONTEXT_LOST`,`glGetError` 报一次 `GL_CONTEXT_LOST`,销毁时不往新 session 发任何记录)。**进程可恢复**(`MOBILEGL_IPC_RECOVER`,默认 1):应用下一次 `eglCreateContext` / `eglCreate*Surface` / `eglInitialize` 拆掉丢失的 session、重新拨号得到新 session,client 侧描述旧 server 的缓存全部清空(发布闩、CSO/sampler 缓存、emitter 闩、create window、applier-reset 序号、persistent map),wire epoch 前进使旧 GLContext 一律视为丢失;surface 保留并在下次 make-current 时于新 session 重建(EGL 对 power-management 事件的语义),Wayland 窗口的 shared image 在新 session 重新分配。in-process server 与 `fd:` 对不可重拨,仍是永久丢失。`MOBILEGL_IPC_RESPAWN`(server 重启后全量重推)仍是具名拒绝。client 死:server 读到 EOF 立即销毁 context 并退出(supervisor 继续服务下一连接)。 +- Linux / WSL / CI never open a window (`EGL_PLATFORM=surfaceless`); Wayland is not supported. A Windows / desktop client is a real shape under the TCP end goal (Windows is the second batch, open question 22); macOS is not split; a Windows machine is not a correctness gate. +- Server death: the client reads a hang-up → **device-lost latch** (GL calls no-op, `eglSwapBuffers` returns `EGL_CONTEXT_LOST`, reset status `GL_UNKNOWN_CONTEXT_RESET`); the `Session::Fail` funnel sends the peer a `SessionFault` frame naming the family (`FatalFamilies.def`). A context created before the latch is permanently lost (`eglMakeCurrent` / `eglSwapBuffers` return `EGL_CONTEXT_LOST`, `glGetError` reports `GL_CONTEXT_LOST` once, and destruction sends no record to a new session). **The process can recover** (`MOBILEGL_IPC_RECOVER`, default 1): the application's next `eglCreateContext` / `eglCreate*Surface` / `eglInitialize` tears down the lost session and dials again for a new one, every client-side cache describing the old server is cleared (the publish latch, the CSO/sampler caches, the emitter latch, create window, the applier-reset sequence number, the persistent map), and the wire epoch advances so that every old GLContext is treated as lost; surfaces are kept and rebuilt in the new session at the next make-current (EGL's semantics for power-management events), and a Wayland window's shared image is reallocated in the new session. An in-process server and the `fd:` pair cannot be re-dialed and remain permanently lost. `MOBILEGL_IPC_RESPAWN` (a full re-push after a server restart) is still refused by name. Client death: the server reads EOF and immediately destroys the context and exits (the supervisor keeps serving the next connection). -#### 15.3.1 Fatal 家族与 wire FatalCode +#### 15.3.1 Fatal families and the wire FatalCode -内部 Fatal 家族(`MG_Pipe/FatalFamilies.def`)远多于 wire 上 `FatalCode` 的 7 个值,所以家族是内部枚举:对端只收到粗粒度的码,细粒度的词留在本地日志与 `SessionFault` 帧的 `family` 字符串里。码只回答「这是哪一类结束」: +The internal Fatal families (`MG_Pipe/FatalFamilies.def`) are far more numerous than the 7 values of the wire `FatalCode`, so a family is an internal enum: the peer only receives the coarse code, while the fine-grained word stays in the local log and in the `family` string of the `SessionFault` frame. The code answers only "which kind of end this is": -- `ProtocolCorruption`:无法正确执行的东西——畸形记录、未实现的 verb / surface、两个角色必须守住的不变式、不合契约的回复。对端读到的是「双方对协议的理解不一致」。 -- `RingOverrun`:共享环或事件通道溢出,是传输容量问题。 -- `SegmentMismatch`:共享段的尺寸放不下某个角色必须放进去的东西(尺寸错,不是一时满)。 -- `AbiMismatch`:两端的布局或协议版本不一致。 -- `ServerCrashed`:等待方归咎于对端的活性结束:排空未完成、apply 线程不在、server 拿不到必需的原生资源(`ResourceUnavailable`)、server 窗口被销毁(`ServerWindowLost`)、GPU 设备丢失(`BackendDeviceLost`,只闩住该 session)。拿不到资源不报 `SegmentMismatch`,那会把错归到共享段尺寸上;wire 上也没有「拿不到资源」的值,新增会改 `wireFingerprint`。 -- `DeviceLost`:只由 device-lost 闩设置,没有家族投影到它。 +- `ProtocolCorruption`: things that cannot be executed correctly—malformed records, an unimplemented verb / surface, an invariant the two roles must uphold, a reply that breaks the contract. What the peer reads is "the two sides disagree on the protocol". +- `RingOverrun`: the shared ring or the event channel overflowed, a transport capacity problem. +- `SegmentMismatch`: the shared segment's size cannot hold what a role must put in it (a wrong size, not a transient fill). +- `AbiMismatch`: the two ends' layout or protocol version disagree. +- `ServerCrashed`: a liveness end the waiter blames on the peer: an incomplete drain, the apply thread gone, the server unable to get a required native resource (`ResourceUnavailable`), the server window destroyed (`ServerWindowLost`), GPU device loss (`BackendDeviceLost`, which latches only that session). An unavailable resource is not reported as `SegmentMismatch`, since that would blame the shared segment's size; the wire has no "resource unavailable" value either, and adding one would change `wireFingerprint`. +- `DeviceLost`: set only by the device-lost latch; no family projects onto it. -### 15.4 共享图像(`shared_image`) +### 15.4 Shared images (`shared_image`) -server 分配并以 dma-buf 描述符导出的颜色缓冲,让一个 client 的帧不离开 GPU 内存就进入另一个 client 的纹理。一行记录(`MGPSharedImageOp`),每个操作都经 reply slot 以 `MGPSharedImageReply` 回答;server 交给 client 的描述符走 aux socket,先于 reply 到达;`ImageId` 由 server 铸造,server 生命期内不复用。`Damage` 是 GL 窗口坐标、左下原点的矩形,0 个 = 整个表面。 +A color buffer that the server allocates and exports as a dma-buf descriptor, letting one client's frame enter another client's texture without leaving GPU memory. One record (`MGPSharedImageOp`), and every operation is answered through a reply slot with `MGPSharedImageReply`; the descriptor the server hands the client goes over the aux socket and arrives before the reply; `ImageId` is minted by the server and is not reused for the server's lifetime. `Damage` is a rectangle in GL window coordinates with a bottom-left origin, and 0 of them = the whole surface. -| 操作 | 语义 | +| Operation | Semantics | |---|---| -| `Allocate` / `Release` | 新建 `Width×Height` 的 `Format` 图像,reply 给出 id,描述符经 aux socket 送达 / 会话放掉对 `ImageId` 的引用 | -| `Import` | 认领 client 在 aux socket 上排队的描述符(`MGPSharedImageFdOffer` 带本记录的 seq);须是本 server 导出的图像,尺寸与格式一致 | -| `Present` | 当前 context 的默认帧缓冲按顶行在先拷进 `ImageId`(窗口帧成为 wl_buffer 的内容),只拷 `Damage`:client 按图像记录它自上次写入后缺的区域;GPU 拷完才回 reply | -| `Attach` | 纹理 `Texture` 的存储变成 `ImageId`(`glEGLImageTargetTexture2DOES`),直到它下一次定义存储的 respecify | -| `QueryBufferAge` | 在流中回答当前 draw surface 的 `EGL_BUFFER_AGE_EXT`(0 = 未知);应用先声明绘制区域(`EGL_KHR_partial_update`)时 `Format = kMGPBufferAgeDamageRegionFollows` | -| `SetDamageRegion` | `eglSetDamageRegionKHR`:本帧将画的区域 | -| `Flush` | 往图像里渲染的会话(X server 的 glamor)的 `glFlush` / `glFinish`:自上个边界用过的图像按 flush 的 fence 发布为已写、已读(隐式同步),发布后回答 | -| `NativeFence` | `EGL_ANDROID_native_fence_sync`:会话已提交工作完成时 signal 的 sync_file(写图像的会话同时做 `Flush` 的发布),经 aux socket 先于 reply 送达,`Format = kMGPNativeFenceFdFollows`;`Format = 0` 表示 server 给不出描述符,reply 发出时工作已完成 | +| `Allocate` / `Release` | create a new `Width×Height` image of `Format`, the reply gives the id, and the descriptor is delivered over the aux socket / the session drops its reference to `ImageId` | +| `Import` | claim the descriptor the client queued on the aux socket (`MGPSharedImageFdOffer` carries this record's seq); it must be an image this server exported, with matching size and format | +| `Present` | the current context's default framebuffer is copied into `ImageId` top row first (the window frame becomes the wl_buffer's contents), copying only `Damage`: the client records, per image, the regions missing since the last write; the reply comes only after the GPU copy completes | +| `Attach` | the storage of texture `Texture` becomes `ImageId` (`glEGLImageTargetTexture2DOES`), until its next respecify that defines storage | +| `QueryBufferAge` | answers in the stream with the current draw surface's `EGL_BUFFER_AGE_EXT` (0 = unknown); when the application first declares the drawing region (`EGL_KHR_partial_update`), `Format = kMGPBufferAgeDamageRegionFollows` | +| `SetDamageRegion` | `eglSetDamageRegionKHR`: the region that will be drawn this frame | +| `Flush` | `glFlush` / `glFinish` of a session rendering into the image (the X server's glamor): images used since the last boundary are published as written and read at the flush's fence (implicit sync), and the answer follows the publication | +| `NativeFence` | `EGL_ANDROID_native_fence_sync`: a sync_file signaled when the session's submitted work completes (a session that writes the image does the `Flush` publication at the same time), delivered over the aux socket before the reply, `Format = kMGPNativeFenceFdFollows`; `Format = 0` means the server cannot give a descriptor and the work was already done when the reply was sent | -### 15.5 EGL 归属:apply 线程终身持有原生 context +### 15.5 EGL ownership: the apply thread holds the native context for life -split 下应用线程从不调用驱动的 `eglMakeCurrent`:`BackendObject_Remote` 的 EGL 虚函数调用 `ServerLoop.h` 的 `Server*` 转发函数,每个都经 `RunSurfaceControlFrame` 成为阻塞控制请求,由 `mgl-srv-apply` 对 server 私有的后端对象执行。 -- 为什么是这条线程:DirectGLES 的 `IsBackendContextCurrentOnThisThread()` 与 `Managers.cpp` 的 `CanTouchGLNow()` 守卫答「否」时静默降级——fence 恒为已 signal、query 返回空句柄、`Present` 不建帧 fence(buffer pool 的回收水位不再前进)、persistent map 拒绝采纳。apply 线程终身持有 context,这些守卫在 server 上都答「是」。 -- 原生 `eglMakeCurrent` 只在 apply 线程当前绑定的 tuple 真正改变时运行,去重分两层:apply 线程上的 `ServerLoop::ApplyMakeCurrent` 用 `ClassifyEglMakeCurrent` 与上次绑定的 tuple 比较,相同即 no-op、不重发 caps,不同则转发并重发 caps 快照,client 的 release-current 只记录(`ClientReleaseCount`)不转发;`BackendObject_DirectGLES::MakeEGLCurrent` 在有传输时,若目标 draw surface 已是本线程原生当前、且虚 tuple 正是那次绑定所为(或那次绑定是 surface 自己的创建),跳过原生调用。同一 surface 上换虚 context 仍原生重绑,因为 `MakeCurrent` 的失效针对的是变了的前端 context。只记一个 tuple:线程上同时只有一个 current context,A → B → A 是三次原生绑定。 -- 在原生绑定可能已改变、或 tuple 指向的 context 可能已不存在的每个事件之后遗忘 tuple(`ServerLoop::ForgetCurrentTuple`):`ReleaseEGLResources`、释放它指向的 surface、surface(重)建(创建时原生绑定新 surface)、后端销毁。EGL 句柄值会复用;记住死 tuple 的代价是静默地没有 current context,遗忘的代价只是一次多余的转发。 -- `ReleaseEGLResources` 与 `~BackendObject_DirectGLES` 必须阻塞:前者本身是控制请求,后者在 apply 线程退出前于该线程执行,`ServerLoop::Stop()` 等它结束;否则 `MobileGL::Destroy()` 会在 server 仍持有 context 时继续往下拆。 -- 对照 `ServerLoopEglTest.MakeCurrentBindsNativelyOncePerContextAndNeverForwardsAClientRelease` 在 EGL 函数表处计数:surface 创建 + 两次相同 make-current + 一次 client release + release 后再绑定 = 一次原生 `eglMakeCurrent`、零次原生 release。 +Under the split the application thread never calls the driver's `eglMakeCurrent`: the EGL virtual functions of `BackendObject_Remote` call the `Server*` forwarders in `ServerLoop.h`, each of which becomes a blocking control request through `RunSurfaceControlFrame` and is executed by `mgl-srv-apply` on the server's private backend object. +- Why this thread: when DirectGLES's `IsBackendContextCurrentOnThisThread()` and `CanTouchGLNow()` in `Managers.cpp` answer "no", the guards degrade silently—fences are always signaled, queries return a null handle, `Present` creates no frame fence (the buffer pool's reclamation watermark stops advancing), and the persistent map refuses adoption. The apply thread holds the context for life, so these guards all answer "yes" on the server. +- The native `eglMakeCurrent` runs only when the tuple currently bound on the apply thread really changes, deduplicated in two layers: on the apply thread, `ServerLoop::ApplyMakeCurrent` compares against the last bound tuple with `ClassifyEglMakeCurrent`; a match is a no-op with no caps resent, a difference is forwarded with a resent caps snapshot, and the client's release-current is only counted (`ClientReleaseCount`), never forwarded; `BackendObject_DirectGLES::MakeEGLCurrent`, when there is a transport, skips the native call if the target draw surface is already natively current on this thread and the virtual tuple is exactly what that binding produced (or that binding was the surface's own creation). Switching virtual contexts on the same surface still binds natively again, because a `MakeCurrent` invalidation targets the frontend context that changed. Only one tuple is kept: a thread has a single current context at a time, so A → B → A is three native bindings. +- The tuple is forgotten (`ServerLoop::ForgetCurrentTuple`) after every event in which the native binding may have changed or the context the tuple points at may no longer exist: `ReleaseEGLResources`, releasing the surface it points at, a surface (re)creation (which natively binds the new surface), and backend destruction. EGL handle values are reused; remembering a dead tuple costs a silent absence of a current context, while forgetting costs only one redundant forward. +- `ReleaseEGLResources` and `~BackendObject_DirectGLES` must block: the former is itself a control request, and the latter runs on the apply thread before that thread exits, with `ServerLoop::Stop()` waiting for it to finish; otherwise `MobileGL::Destroy()` would keep tearing down while the server still holds the context. +- The control `ServerLoopEglTest.MakeCurrentBindsNativelyOncePerContextAndNeverForwardsAClientRelease` counts at the EGL function table: surface creation + two identical make-currents + one client release + a bind after the release = one native `eglMakeCurrent`, zero native releases. diff --git a/docs/Disaggregated/design/09-build-switches-counters.md b/docs/Disaggregated/design/09-build-switches-counters.md index 604d4815..a9e02eca 100644 --- a/docs/Disaggregated/design/09-build-switches-counters.md +++ b/docs/Disaggregated/design/09-build-switches-counters.md @@ -1,85 +1,85 @@ -# 构建布局、开关与计数器(原 ARCHITECTURE §16、附 A、附 B) +# Build layout, switches and counters (formerly ARCHITECTURE §16, appendices A and B) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design details. The design points and the index of all chapters are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; an `ARCHITECTURE.md §N` in a code comment is found by its number here. -## 16. 构建布局 +## 16. Build layout ``` -MobileGL/MG_Pipe/ 永远进构建:*.def 目录与表、MGPipe*.h payload / 句柄 / 回调、PipeApply、PipeRoute、generated/*.inc -MobileGL/MG_Impl/Pipe/ Tracker、PipeFill、SlotAllocator、CsoCache、CompositeResolver、ResourceTracker、SetHashSuppressor、*Emit.h +MobileGL/MG_Pipe/ always in the build: the *.def catalog and tables, MGPipe*.h payloads / handles / callbacks, PipeApply, PipeRoute, generated/*.inc +MobileGL/MG_Impl/Pipe/ Tracker, PipeFill, SlotAllocator, CsoCache, CompositeResolver, ResourceTracker, SetHashSuppressor, *Emit.h MobileGL/MG_Backend/MGPipe/ PipeInputs.{h,cpp} -MobileGL/MG_Remote/ 仅 MOBILEGL_BUILD_DISAGGREGATED:CONTRACT-*.md、CapsCodec、FatalFamilies.def / FatalFunnel、Handshake.h - Protocol/ protocol.fbs、generated/、SurfaceOpCodec、mg_protocol_base.h - Transport/ ITransport、SocketTransport、InProcessTransport、ILink、ShmLink、StreamLink、Ring、SessionRings、ReplySlot、EventRing、 - Doorbell、ShmSegment(+Posix/Win32)、FdPassing、Framing、AuthToken、ControlInbox、LinkMetrics、WireLog - Wire/ PipeWireCodec(记录编解码、WireVerbSink) - Client/ BackendObject_Remote、ClientSession、EmitTables、WireTables、CapsMirror、PersistentMapTracker、GpuWritePending - Server/ PipeApplier、ServerLoop、ServerSession、ServerMain / ServerEntry / ServerSpawn、PreAuthGate、StagedShadow、StagedTextureStore、 - SurfaceControlFrame、ServerDisplay、InProcessServer、DisplayServerJni +MobileGL/MG_Remote/ only with MOBILEGL_BUILD_DISAGGREGATED: CONTRACT-*.md, CapsCodec, FatalFamilies.def / FatalFunnel, Handshake.h + Protocol/ protocol.fbs, generated/, SurfaceOpCodec, mg_protocol_base.h + Transport/ ITransport, SocketTransport, InProcessTransport, ILink, ShmLink, StreamLink, Ring, SessionRings, ReplySlot, EventRing, + Doorbell, ShmSegment(+Posix/Win32), FdPassing, Framing, AuthToken, ControlInbox, LinkMetrics, WireLog + Wire/ PipeWireCodec (record codec, WireVerbSink) + Client/ BackendObject_Remote, ClientSession, EmitTables, WireTables, CapsMirror, PersistentMapTracker, GpuWritePending + Server/ PipeApplier, ServerLoop, ServerSession, ServerMain / ServerEntry / ServerSpawn, PreAuthGate, StagedShadow, StagedTextureStore, + SurfaceControlFrame, ServerDisplay, InProcessServer, DisplayServerJni ``` -- `MOBILEGL_BUILD_DISAGGREGATED`(默认 OFF)追加 `MG_Remote/**`;OFF 时 `MG_Config::Transport` 是 `constexpr Monolith`。`MOBILEGL_BUILD_DISAGGREGATED_INPROC` 隐含前者并加角色隔离:两个角色靠 apply 线程与控制邮箱分开,而不是给 1494 个 `pGLContext->` 读点加 TLS。 -- `MOBILEGL_TRANSPORT = monolith | inproc | spawn` 是**拓扑**(G1 相关);控制面与数据面由 §11.9 的两个变量选。**split build 不设 `MOBILEGL_TRANSPORT` 时是 monolith 对照臂**。 -- 三个构建 flavour(P13 起):默认(单进程记录臂,不编 `MG_Remote`,出货形态)、verify、split;Android 两份 APK flavour(单进程 / split)。pull 构建与 `MOBILEGL_PIPE_PUSH` CMake 选项在 P13 删除。 -- 模块(P13 W7):`SOURCE_FILES` 按 link ratchet 的 PARTITION 拆成七个 OBJECT 库,`MobileGL` / `MobileGL_s` 由它们拼成;split 构建的 `MobileGL_server_linkcheck` 只链 SERVER 与 SHARED 模块并 `--no-undefined`,基线外的前端引用在构建时就失败(`scripts/ci/server_link_check.py`)。记录臂的 server 端代码在 `MG_Backend/Record/`(`RecordVerbSink`、`StagedShadow`、`StagedTextureStore`),客户端 verb 发射在 `MG_Impl/Pipe/Verb/`,不再依赖 `MG_Remote`。 -- 测试接线:ctest `ENVIRONMENT` 用 `mgl_itest_join_environment(...)` 构造;每条 split / spawn / tcp 条目带独立日志路径,日志按角色分文件(`.client.log` / `.server.log`);spawn、tcp 车道与 split 名集合一致(`scripts/ci/spawn_lane_parity.py`),每条目记 arm 证明。 -- CI(`.github/workflows/test.yml`、`apk.yml`):`pipe-gates`(G1–G8、生成器 self-test、符号报告、dirty-surface、字段归属、G5、文档引用 lint)、`flatc-check`、include 闭包、各 flavour 的 build / integration / retrace 车道、APK + AVD。两份 workflow 里的 `feat/disaggregated` 触发器是临时的,合入 `dev` 前移除。 +- `MOBILEGL_BUILD_DISAGGREGATED` (default OFF) adds `MG_Remote/**`; when OFF, `MG_Config::Transport` is a `constexpr Monolith`. `MOBILEGL_BUILD_DISAGGREGATED_INPROC` implies the former and adds role isolation: the two roles are separated by the apply thread and the control mailbox, rather than by adding TLS to the 1494 `pGLContext->` read points. +- `MOBILEGL_TRANSPORT = monolith | inproc | spawn` is the **topology** (G1-relevant); the control plane and data plane are selected by the two variables in §11.9. **A split build with `MOBILEGL_TRANSPORT` unset is the monolith control arm**. +- Three build flavors (since P13): default (the monolith record arm, with `MG_Remote` not compiled, the shipping shape), verify, and split; Android has two APK flavors (monolith / split). The pull build and the `MOBILEGL_PIPE_PUSH` CMake option are deleted in P13. +- Modules (P13 W7): `SOURCE_FILES` is split into seven OBJECT libraries according to the link ratchet's PARTITION, and `MobileGL` / `MobileGL_s` are assembled from them; in a split build `MobileGL_server_linkcheck` links only the SERVER and SHARED modules with `--no-undefined`, so a frontend reference outside the baseline fails at build time (`scripts/ci/server_link_check.py`). The record arm's server-side code is in `MG_Backend/Record/` (`RecordVerbSink`, `StagedShadow`, `StagedTextureStore`), and client verb emission is in `MG_Impl/Pipe/Verb/`, no longer depending on `MG_Remote`. +- Test wiring: the ctest `ENVIRONMENT` is built with `mgl_itest_join_environment(...)`; every split / spawn / tcp entry has its own log path, and logs are split per role (`.client.log` / `.server.log`); the spawn and tcp lanes match the split name set (`scripts/ci/spawn_lane_parity.py`), and each entry records its arm proof. +- CI (`.github/workflows/test.yml`, `apk.yml`): `pipe-gates` (G1–G8, the generator self-test, the symbol report, dirty-surface, field ownership, G5, the documentation-reference lint), `flatc-check`, the include closure, the build / integration / retrace lanes of each flavor, APK + AVD. The `feat/disaggregated` triggers in both workflows are temporary and are removed before merging into `dev`. -### 16.1 集成测试车道的接线规则 +### 16.1 Wiring rules for the integration test lanes -`MG_IntegrationTest/CMakeLists.txt` 的每条车道都要能因它存在的理由变红(§13.2),接线规则: -- 读库日志的用例必须独占日志:库以 `fopen(path, "w")` 打开日志,同一路径上的每个进程启动时都截断它,`ctest -j` 下读者会读到邻居截断后的文件,症状与「计数从未发出」相同。条目因此带私有 `MOBILEGL_LOG_FILE_PATH`,过滤器只选这一个用例;车道必须跑整个 scenario(重新过滤会改测试名)时,加以日志命名的 `RESOURCE_LOCK`,ctest 不会同时运行持同一把锁的条目。 -- 选臂的每个变量都写成条目自己的 ctest `ENVIRONMENT` 属性:属性只覆盖它写出的变量,其余从 job 环境漏进来(job 级 `MOBILEGL_TRANSPORT=inproc` 会把没钉 `monolith` 的 monolith 条目悄悄变成又一条 split)。 -- ctest 不把 SKIP 算失败,跳光的车道和全过的车道一样绿:必须真跑的车道钉 `MOBILEGL_ITEST_REQUIRE_GPU=1`,让不可用的 harness 变成失败;功能 opt-in(如 `MOBILEGL_ESPRYT_ENABLE_TEXTURE_VIEW=1`)必须到达每个臂里读它的进程,tcp 臂的 server 由 `TcpServer.Start` fixture 预先启动、不继承 client 条目的环境,所以也要设在 fixture 上。 -- `ctest -L` 按正则子串匹配:新标签不得包含任何被不加锚点选择的已有标签,所以限定词放在中间(`integration-magma-all-spawn` 不含 `integration-magma-spawn`,`integration-magma-spawn-buffers` 不含 `integration-magma-buffers`);只选一个标签时写 `'^label$'`。 -- 门控车道带一个私有的第二标签并以 `--no-tests=error` 运行:构建缺少该选项时匹配为空即失败,而不是零条目的绿。 -- 三条传输臂:`Split.` 为 inproc,server 是测试进程里的 apply 线程;`Spawn.` 的 server 子进程继承 `::environ`(`ServerSpawn.cpp` 只去掉 `MOBILEGL_TRANSPORT` 与非 server 自有的 `MOBILEGL_IPC_*`);`Tcp.` 的 server 是整条车道共享的 `TcpServer.Start` fixture,由 `scripts/ci/tcp_server_fixture.py` 以它自己的环境启动一次,每个 Hello fork 一个 session 子进程。 -- 条目 ctest `ENVIRONMENT` 里由 server 读取的旋钮只到达 inproc 与 spawn 的 server;tcp 副本会以默认臂运行却顶着声称旋钮的名字,永远不会红。这类条目只注册 split + spawn(Magma 的列入 `scripts/ci/spawn_lane_parity.py` 的 `MAGMA_SERVER_ENV_KNOB_NO_TCP`),旋钮取默认值的孪生条目保留三条臂;要 tcp 臂就得让 fixture 带上旋钮:对整条车道无害的追加到 `TcpServer.Start` 的 `ENVIRONMENT`,否则另起一个带旋钮的 supervisor(`P8Coverage.cmake`)。只能在本进程读取的探针(描述符池普查、server loop 挂钩、server 缓存窥视、验证层输出)只注册 inproc(`MAGMA_INPROC_ONLY`)。 -- Magma 分三层:门控的 `integration-magma-{split,spawn,tcp}` 是手工布置、各带 flavour(strict + 双块、adopt 档、run-ahead credit、cache 钉定)的车道,测绿后才进 CI 门;`integration-magma-all-*` 重放每次 `mgl_itest_register_split_arms` 调用;`integration-magma-full-*` 跑整个集成二进制减去 `MGL_ITEST_MONOLITH_MECHANISM_FILTER` 与 `DualBlockScenario`。后两层不进任何 CI 门,用例随修复其阻塞点的提交升入门控层。 -- `MGITEST_SPLIT_LANE=1` 武装 `ScenarioFixture` 的析构断言:case 必须推进 client 编码器的记录序号,tcp 臂还要证明没有本地 server 子进程。它只适合每条都绘制的精选车道;整二进制集合(`integration-magma-full-*`、`integration-verify-split`)不设它,因为纯查询 case 由 `CapsMirror` 回答、不产生记录,代价是这些集合不证明记录过了线。 +Every lane in `MG_IntegrationTest/CMakeLists.txt` must be able to go red for the reason it exists (§13.2); the wiring rules: +- A case that reads the library log must own the log exclusively: the library opens the log with `fopen(path, "w")`, and every process starting on the same path truncates it, so under `ctest -j` a reader sees a neighbor's truncated file, with the same symptom as "the counter was never emitted". An entry therefore carries a private `MOBILEGL_LOG_FILE_PATH`, and the filter selects only that case; when a lane must run a whole scenario (re-filtering would change the test names), it adds a `RESOURCE_LOCK` named after the log, and ctest will not run entries holding the same lock at the same time. +- Every variable that selects an arm is written as the entry's own ctest `ENVIRONMENT` property: the property overrides only the variables it states, and the rest leak in from the job environment (a job-level `MOBILEGL_TRANSPORT=inproc` quietly turns a monolith entry that does not pin `monolith` into another split). +- ctest does not count SKIP as a failure, so a lane that skips everything is as green as a lane that passes everything: a lane that must really run pins `MOBILEGL_ITEST_REQUIRE_GPU=1`, so an unavailable harness becomes a failure; a feature opt-in (such as `MOBILEGL_ESPRYT_ENABLE_TEXTURE_VIEW=1`) must reach the process that reads it in each arm, and the tcp arm's server is started ahead of time by the `TcpServer.Start` fixture and does not inherit the client entry's environment, so it must be set on the fixture as well. +- `ctest -L` matches by regular-expression substring: a new label must not contain any existing label that is selected without anchors, so the qualifier goes in the middle (`integration-magma-all-spawn` does not contain `integration-magma-spawn`, and `integration-magma-spawn-buffers` does not contain `integration-magma-buffers`); selecting a single label is written `'^label$'`. +- A gated lane carries a private second label and runs with `--no-tests=error`: when the build lacks the option the match is empty and fails, rather than a zero-entry green. +- Three transport arms: `Split.` is inproc, and the server is the apply thread in the test process; `Spawn.`'s server child inherits `::environ` (`ServerSpawn.cpp` removes only `MOBILEGL_TRANSPORT` and the `MOBILEGL_IPC_*` that are not server-owned); `Tcp.`'s server is the `TcpServer.Start` fixture shared by the whole lane, started once by `scripts/ci/tcp_server_fixture.py` with its own environment, forking one session child per Hello. +- A knob read by the server in an entry's ctest `ENVIRONMENT` reaches only the inproc and spawn servers; a tcp copy would run the default arm under a name claiming the knob and would never go red. Such entries register split + spawn only (for Magma they are listed in `MAGMA_SERVER_ENV_KNOB_NO_TCP` in `scripts/ci/spawn_lane_parity.py`), and the twin entry with the knob at its default keeps all three arms; a tcp arm requires the fixture to carry the knob: append it to `TcpServer.Start`'s `ENVIRONMENT` when it is harmless to the whole lane, otherwise start a separate supervisor that carries it (`P8Coverage.cmake`). Probes that can only be read in this process (the descriptor-pool census, the server loop hooks, the server cache peeking, validation-layer output) register for inproc only (`MAGMA_INPROC_ONLY`). +- Magma has three layers: the gated `integration-magma-{split,spawn,tcp}` lanes are hand-arranged, each with its flavor (strict + dual block, adoption tier, run-ahead credit, cache pinning), and enter the CI gate only after passing; `integration-magma-all-*` replays every `mgl_itest_register_split_arms` call; `integration-magma-full-*` runs the whole integration binary minus `MGL_ITEST_MONOLITH_MECHANISM_FILTER` and `DualBlockScenario`. The last two layers enter no CI gate, and a case is promoted to the gated layer by the commit that fixes its blocking point. +- `MGITEST_SPLIT_LANE=1` arms the `ScenarioFixture` destructor assertion: the case must advance the client encoder's record sequence number, and the tcp arm must also prove there is no local server child process. It suits only curated lanes where every case draws; the whole-binary sets (`integration-magma-full-*`, `integration-verify-split`) do not set it, because pure query cases are answered by `CapsMirror` and produce no records, at the cost that these sets do not prove records crossed the wire. -## 附 A:开关 +## Appendix A: switches -CMake:`MOBILEGL_BUILD_DISAGGREGATED`(OFF)、`MOBILEGL_BUILD_DISAGGREGATED_INPROC`(OFF,隐含前者)、`MOBILEGL_PIPE_VERIFY`(OFF,永不出货)、`MOBILEGL_BUILD_SERVER_SPIKE`(仅 Android spike)、`MOBILEGL_FLATC_EXECUTABLE`(只服务 `flatc-check`)。`MOBILEGL_PIPE_PUSH` 与 `MOBILEGL_PIPE_LEGACY_MEMOS` 在 P13 删除(旧缓存里的 OFF 只告警并忽略)。 +CMake: `MOBILEGL_BUILD_DISAGGREGATED` (OFF), `MOBILEGL_BUILD_DISAGGREGATED_INPROC` (OFF, implies the former), `MOBILEGL_PIPE_VERIFY` (OFF, never ships), `MOBILEGL_BUILD_SERVER_SPIKE` (Android spike only), `MOBILEGL_FLATC_EXECUTABLE` (serves `flatc-check` only). `MOBILEGL_PIPE_PUSH` and `MOBILEGL_PIPE_LEGACY_MEMOS` are deleted in P13 (an OFF in an old cache only warns and is ignored). -运行时,MGPipe(`MobileGL/Config.h`、`ConfigLoader.cpp`): +At runtime, MGPipe (`MobileGL/Config.h`, `ConfigLoader.cpp`): -| 变量 | 默认 | 说明 | +| Variable | Default | Description | |---|---|---| -| `MOBILEGL_PIPE_PUSH` | `0x3fff` | 子系统位图(`MG_Pipe/MGPipe.h`,位永不复用);P13 起位 0–13 固定开,清任何一位都在启动时具名拒绝;只剩位 63("关 CSO 内容寻址"的行为对照)可设 | -| `MOBILEGL_PIPE_VERIFY` / `_VERIFY_FATAL` / `_VERIFY_CORRUPT` | 0 / 1 / 空 | 影子比对与它的阴性对照。比对器只编进 verify 构建,其他构建里 `MOBILEGL_PIPE_VERIFY=1` 只告警;`_VERIFY_CORRUPT` 不进 `Config.h`,只有 verify 构建在比对器武装时读它(`PipeFill.cpp` 的 `ArmVerify`,同样经环境与系统配置文件)。poison 的阴性对照没有运行时开关:集成测试的 harness 标记 `MGITEST_POISON_OMIT` 由重新 exec 的子进程经 verify 构建才有的 `MGPipeSetPoisonOmission` 武装(`Harness/PoisonOmissionArm.h`) | -| `MOBILEGL_PIPE_STATS` / `_STATS_PERIOD` / `_STATS_FILE` | 0 / 120 / 空 | 边界计数器(附 B);dump 按角色写 `.client.json` / `.server.json` | -| `MOBILEGL_PIPE_INDEX_MIRROR_MB` | 64 | 索引镜像预算(P8);`_LEGACY_MEMOS`、`_TEXEL_RETAIN_MB`、`_HANDLE_ABA_CONTROL` 随各自的臂在 P13 删除 | +| `MOBILEGL_PIPE_PUSH` | `0x3fff` | subsystem bitmap (`MG_Pipe/MGPipe.h`, bits are never reused); since P13 bits 0–13 are fixed on, and clearing any of them is refused by name at startup; only bit 63 ("the behavior control for turning off CSO content addressing") can still be set | +| `MOBILEGL_PIPE_VERIFY` / `_VERIFY_FATAL` / `_VERIFY_CORRUPT` | 0 / 1 / empty | the shadow comparison and its negative controls. The comparator is compiled only into the verify build; in other builds `MOBILEGL_PIPE_VERIFY=1` only warns; `_VERIFY_CORRUPT` is not in `Config.h`, and only the verify build reads it when the comparator is armed (`ArmVerify` in `PipeFill.cpp`, likewise through the environment and the system configuration file). The poison negative control has no runtime switch: the integration test's harness flag `MGITEST_POISON_OMIT` is armed by a re-exec'd child process through `MGPipeSetPoisonOmission`, which only the verify build has (`Harness/PoisonOmissionArm.h`) | +| `MOBILEGL_PIPE_STATS` / `_STATS_PERIOD` / `_STATS_FILE` | 0 / 120 / empty | boundary counters (Appendix B); the dump is written per role as `.client.json` / `.server.json` | +| `MOBILEGL_PIPE_INDEX_MIRROR_MB` | 64 | the index mirror budget (P8); `_LEGACY_MEMOS`, `_TEXEL_RETAIN_MB` and `_HANDLE_ABA_CONTROL` are deleted with their arms in P13 | -运行时,传输与 IPC: +At runtime, transport and IPC: -| 变量 | 默认 | 说明 | +| Variable | Default | Description | |---|---|---| -| `MOBILEGL_TRANSPORT` | `monolith` | 拓扑:`monolith` / `inproc` / `spawn` | -| `MOBILEGL_IPC_CONTROL` / `MOBILEGL_IPC_DATA` | `fork` / `auto` | 控制面端点与数据面(§11.9);`MOBILEGL_IPC_SERVER_PATH` 定位 fork 出的 server | -| `MOBILEGL_IPC_TOKEN` / `MOBILEGL_IPC_REQUIRE_SAME_BUILD` | 空 / 0 | 令牌(≥16 字节;无令牌只允许 loopback);要求两端同一构建(车道纪律) | -| `MOBILEGL_IPC_PREAUTH_*` / `MOBILEGL_IPC_AUTH_BACKOFF_*` | — | server 预认证的上限与失败退避(Ph) | -| `MOBILEGL_IPC_CONTROL_TIMEOUT_MS` / `MOBILEGL_IPC_COLD_START_MS` | 5000 / 20000 | 控制回复的稳态上限与冷启动预算 | -| `MOBILEGL_IPC_LOG_FORWARD` | 远端时开 | server 日志经控制连接前送,client 写进自己的 `.server.log` | -| `MOBILEGL_IPC_SURFACE` | `offscreen` | `server` = 使用 server 自有窗口,client 无头(P12) | -| `MOBILEGL_IPC_RING_MB` / `MOBILEGL_IPC_STAGE_MB` | 8 / 32 | `SEG_CMD` / `SEG_STAGE`;stage 的 1/4 是内容分块预算 | -| `MOBILEGL_IPC_RUN_AHEAD` | 1 | P5e run-ahead;只是合取式的一半(server 须发布 `kCapRunAheadApply`);`0` 是 A/B 对照 | -| `MOBILEGL_FRAMES_IN_FLIGHT` | 3 | 1..64,两个后端共用(旧名 `MOBILEGL_MAGMA_FRAMESINFLIGHT` 为弃用别名):Magma 的帧上下文数;Espryt 在 present S 后等待帧 S+1-N 完成;split 的 present credit 由它导出为 max(1, N-2)(P15) | -| `MOBILEGL_IPC_PRESENT_CREDIT` | 由 `MOBILEGL_FRAMES_IN_FLIGHT` 导出(默认 1) | 1..8,§14;显式设置覆盖导出值,仅供实验 | -| `MOBILEGL_IPC_POLL_ESCALATE` | 64 | 未报告 fence 的零超时轮询本地答"未完成",同一 fence 连续第 N 次才往返(P10,`CONTRACT-P10.md` §1);`0` = 每次轮询都往返,是 A/B 对照 | -| `MOBILEGL_IPC_BATCH_WAITS` | 1 | lockstep 下值类记录发布即返回;verify 构建里 `MOBILEGL_PIPE_VERIFY=1` 强制 0(`RUN_AHEAD` 同样强制 0,`ROLE_SPLIT_STATE` 强制关;其他构建不改它们) | -| `MOBILEGL_IPC_EVENT_WAIT_MS` | 2000 | 反向事件遇满环时 server 等 client 排空的整笔预算(§11.7) | -| `MOBILEGL_IPC_WIRE_DEFERRED_MB` | 64 | Magma wire 臂延迟回收的水位线;`0` 是 M2 阴性对照 | -| `MOBILEGL_IPC_PERSISTENT_HASH_SUPPRESS` | 1 | persistent-map 推送只推变化的块(粒度固定 64 KiB,`PersistentMapTracker::BlockBytes()`);`0` 是整段推送的 A/B 对照 | -| `MOBILEGL_IPC_ADOPT_TIER` | 未设 = T0 | 未设(用户 2026-09-29 定为缺省)= 能用就 T0,不能用(stream、无 AHB、POST 失败、server 不允许)安静回退 T2:只 MGLOG_D、照样计数;`0` = 点名要 T0,回退有具名行(A1 的 `Refuse{AdoptTierOnStream}` 等);`1` = T1 已关,具名拒绝后 T2;`2` = T2(P11 前的缺省)。`CONTRACT-P11.md` B2 | -| `MOBILEGL_IPC_ALLOW_ADOPT_T0` | 1 | server 自有:`0` = 永不批准 T0(会话走 T2),经 `ServerSpawn` 保留 | -| `MOBILEGL_IPC_STRICT_ERRORS` / `MOBILEGL_IPC_AUDIT` / `MOBILEGL_IPC_ROLE_SPLIT_STATE` | 0 / 0 / 1 | 残余输入读升级为 Fatal / 退休 staging 填 `0xDD` / 双块(P5f;P15 起默认开,`0` 关闭,阴性对照显式设 0;双块下 barriered fill 写 client 块,不再 quiesce applier) | -| `MOBILEGL_IPC_SPIN_US` / `MOBILEGL_IPC_SERVER_AFFINITY` | 50 / `auto` | park 前自旋预算 / apply 线程亲和(Redmi 内核忽略) | -| `MOBILEGL_IPC_RECOVER` | 1 | session 因 device loss 结束后,应用下一次 `eglCreateContext` / `eglCreate*Surface` / `eglInitialize` 重新拨号得到新 session(旧 context 保持丢失,surface 在新 session 重建);`0` = 丢失对整个进程永久 | -| `MOBILEGL_IPC_RESPAWN` | — | 具名拒绝:没有阶段实现 server 重启后的全量重推 | +| `MOBILEGL_TRANSPORT` | `monolith` | topology: `monolith` / `inproc` / `spawn` | +| `MOBILEGL_IPC_CONTROL` / `MOBILEGL_IPC_DATA` | `fork` / `auto` | the control-plane endpoint and the data plane (§11.9); `MOBILEGL_IPC_SERVER_PATH` locates the forked server | +| `MOBILEGL_IPC_TOKEN` / `MOBILEGL_IPC_REQUIRE_SAME_BUILD` | empty / 0 | the token (≥16 bytes; without a token only loopback is allowed); require the same build on both ends (lane discipline) | +| `MOBILEGL_IPC_PREAUTH_*` / `MOBILEGL_IPC_AUTH_BACKOFF_*` | — | the server pre-authentication limits and the failure backoff (Ph) | +| `MOBILEGL_IPC_CONTROL_TIMEOUT_MS` / `MOBILEGL_IPC_COLD_START_MS` | 5000 / 20000 | the steady-state cap on control replies and the cold-start budget | +| `MOBILEGL_IPC_LOG_FORWARD` | on when remote | server logs are forwarded over the control connection, and the client writes them into its own `.server.log` | +| `MOBILEGL_IPC_SURFACE` | `offscreen` | `server` = use the server's own window, with the client headless (P12) | +| `MOBILEGL_IPC_RING_MB` / `MOBILEGL_IPC_STAGE_MB` | 8 / 32 | `SEG_CMD` / `SEG_STAGE`; a quarter of stage is the content chunking budget | +| `MOBILEGL_IPC_RUN_AHEAD` | 1 | P5e run-ahead; only one half of the conjunction (the server must publish `kCapRunAheadApply`); `0` is the A/B control | +| `MOBILEGL_FRAMES_IN_FLIGHT` | 3 | 1..64, shared by both backends (the old name `MOBILEGL_MAGMA_FRAMESINFLIGHT` is a deprecated alias): the number of Magma frame contexts; Espryt waits for frame S+1-N to complete after presenting S; the split derives the present credit from it as max(1, N-2) (P15) | +| `MOBILEGL_IPC_PRESENT_CREDIT` | derived from `MOBILEGL_FRAMES_IN_FLIGHT` (default 1) | 1..8, §14; an explicit setting overrides the derived value, for experiments only | +| `MOBILEGL_IPC_POLL_ESCALATE` | 64 | a zero-timeout poll for an unreported fence answers "not complete" locally, and only the Nth consecutive poll of the same fence makes a roundtrip (P10, `CONTRACT-P10.md` §1); `0` = a roundtrip on every poll, the A/B control | +| `MOBILEGL_IPC_BATCH_WAITS` | 1 | under lockstep, value-class records return as soon as they publish; in the verify build `MOBILEGL_PIPE_VERIFY=1` forces 0 (`RUN_AHEAD` likewise forces 0, `ROLE_SPLIT_STATE` forces it off; other builds do not change them) | +| `MOBILEGL_IPC_EVENT_WAIT_MS` | 2000 | the whole budget for the server to wait for the client to drain when a reverse event meets a full ring (§11.7) | +| `MOBILEGL_IPC_WIRE_DEFERRED_MB` | 64 | the watermark for deferred reclamation on the Magma wire arm; `0` is the M2 negative control | +| `MOBILEGL_IPC_PERSISTENT_HASH_SUPPRESS` | 1 | persistent-map pushes send only the changed blocks (fixed 64 KiB granularity, `PersistentMapTracker::BlockBytes()`); `0` is the A/B control that pushes the whole range | +| `MOBILEGL_IPC_ADOPT_TIER` | unset = T0 | unset (the user made this the default on 2026-09-29) = T0 when it can be used, with a quiet fallback to T2 when it cannot (stream, no AHB, POST failure, server does not allow it): only MGLOG_D, counted as usual; `0` = ask for T0 by name, and the fallback has a named line (A1's `Refuse{AdoptTierOnStream}` and so on); `1` = T1 is off, a named refusal and then T2; `2` = T2 (the pre-P11 default). `CONTRACT-P11.md` B2 | +| `MOBILEGL_IPC_ALLOW_ADOPT_T0` | 1 | server-owned: `0` = never approve T0 (the session goes T2), preserved through `ServerSpawn` | +| `MOBILEGL_IPC_STRICT_ERRORS` / `MOBILEGL_IPC_AUDIT` / `MOBILEGL_IPC_ROLE_SPLIT_STATE` | 0 / 0 / 1 | residual input reads escalate to Fatal / retired staging is filled with `0xDD` / dual block (P5f; on by default since P15, `0` turns it off, and the negative control sets 0 explicitly; under dual block the barriered fill writes the client block and no longer quiesces the applier) | +| `MOBILEGL_IPC_SPIN_US` / `MOBILEGL_IPC_SERVER_AFFINITY` | 50 / `auto` | pre-park spin budget / apply-thread affinity (ignored by the Redmi kernel) | +| `MOBILEGL_IPC_RECOVER` | 1 | after a session ends from device loss, the application's next `eglCreateContext` / `eglCreate*Surface` / `eglInitialize` dials again for a new session (old contexts stay lost, surfaces are rebuilt in the new session); `0` = the loss is permanent for the whole process | +| `MOBILEGL_IPC_RESPAWN` | — | refused by name: no phase implements a full re-push after a server restart | -显式不设立:`MOBILEGL_IPC_PROGRAM`(没有 relink 档)、`MOBILEGL_IPC_VALIDATE_SERVER`。计划中未接线:`MOBILEGL_IPC_IDLE_EXIT_S`(未解析)。 +Explicitly not introduced: `MOBILEGL_IPC_PROGRAM` (there is no relink tier), `MOBILEGL_IPC_VALIDATE_SERVER`. Planned but not wired: `MOBILEGL_IPC_IDLE_EXIT_S` (unresolved). -## 附 B:边界计数器(`MobileGL/MG_Util/Metrics/PipeStats.h`) +## Appendix B: boundary counters (`MobileGL/MG_Util/Metrics/PipeStats.h`) -关闭时每站点一次全局 load + 一条永不命中的分支。字节类(stage buffer / texture / UBO / client 数组、`pmap`、`resid`、`csob-blob`、`seg` = 写进 `SEG_STAGE` 的字节)、调用类(`draws`、`accessor-calls`、纹理上传 emit / box / rect / jobs、`csom` / `csob`、`mpr`、`trp`、`rsp`、`wrec`、server 应用的控制记录 `ar`(applier_reset)/ `od`(object_death)、`maxrec` / `ringwraps` / `ringpads` / `ringwaits`、门铃 `srv` / `srvpark` / `cli` / `clipark`)与六个 memo 门的 hit/miss。每 `MOBILEGL_PIPE_STATS_PERIOD` 帧一条 `MGPipe stats:` 汇总行,按角色写日志。读法陷阱:`accessor-calls` 是静态下界,判性能只看 CPU 时间;spawn 下 client 不推进帧窗口(`frames=0`),窗口化字段在 spawn client 上无效,run total 仍有效(见 git 历史 §12.1)。站点清单(哪些路径**没有**接线)写在 `PipeStats.cpp` 头部,那份清单是契约。 +When off, each site costs one global load + one branch that never hits. The byte kinds (stage buffer / texture / UBO / client arrays, `pmap`, `resid`, `csob-blob`, `seg` = bytes written into `SEG_STAGE`), the call kinds (`draws`, `accessor-calls`, texture upload emit / box / rect / jobs, `csom` / `csob`, `mpr`, `trp`, `rsp`, `wrec`, server-applied control records `ar` (applier_reset) / `od` (object_death), `maxrec` / `ringwraps` / `ringpads` / `ringwaits`, the doorbells `srv` / `srvpark` / `cli` / `clipark`), and the hit/miss of the six memo gates. Every `MOBILEGL_PIPE_STATS_PERIOD` frames there is one `MGPipe stats:` summary line, written to the log per role. Reading traps: `accessor-calls` is a static lower bound, and judging performance looks only at CPU time; under spawn the client does not advance the frame window (`frames=0`), so windowed fields are invalid on a spawn client while the run total stays valid (see git history §12.1). The site list (which paths are **not** wired) is at the top of `PipeStats.cpp`, and that list is a contract. diff --git a/docs/Disaggregated/design/10-phase-shapes.md b/docs/Disaggregated/design/10-phase-shapes.md index 8759fee3..7951b126 100644 --- a/docs/Disaggregated/design/10-phase-shapes.md +++ b/docs/Disaggregated/design/10-phase-shapes.md @@ -1,17 +1,17 @@ -# 各阶段的落地形状(原 ARCHITECTURE §17) +# Landing shapes of each phase (formerly ARCHITECTURE §17) -> 设计细节。设计要点与全部章节的索引见 [`../ARCHITECTURE.md`](../ARCHITECTURE.md)。章节编号沿用原 `ARCHITECTURE.md`,代码注释里的 `ARCHITECTURE.md §N` 按编号在这里找到。 +> Design detail. The design points and the index of all sections are in [`../ARCHITECTURE.md`](../ARCHITECTURE.md). Section numbers follow the original `ARCHITECTURE.md`; an `ARCHITECTURE.md §N` in a code comment is found here by that number. -## 17. 阶段落地形状(索引) +## 17. Phase landing shapes (index) -各阶段落地时的形状、偏差与论证原文在 notes 里;下表只列仍然生效的规则。 +The shapes, deviations and rationale text for each phase's landing are in the notes; the table below lists only the rules that still apply. -| 原节 | 主题 | 仍生效的规则 | 全文 | +| Original section | Topic | Rules that still apply | Full text | |---|---|---|---| -| 17.1 | verb barrier 与诚实的同地址空间传输(P5) | 同地址空间不得成为旁路(R-2):encoder 把 `MGHostSpan::Ptr` 恒写 `nullptr`;reply 以记录序号为 slot id(R-3);等待看门狗 120 s 只判死锁,不是性能门 | git 历史 | -| 17.2 | 后端槽三类、caps、tight readback(P5) | A 本地答 / B 发射 / C 具名拒绝,永不回落 monolith(R-4);能力只读 `CallMask`(R-8);`ReadPixels` 线上恒 tight,client 按自己的 pack state 散射 | 同上 | -| 17.3 | server 角色、shadow 与退出(P5) | apply 线程终身持有 native context,EGL 罕见操作经控制邮箱进 apply 线程;staged shadow 只交 server-owned 拷贝;有界退出顺序 | 同上 | -| 17.4 | lane 隔离(P5) | 每条 split 条目私有日志;E1 与 E3(a) 的对照是常驻用例(`RemoteWaitBoundaryControl.AnUnwaitedPublishIsSeenAsNoWait`、`PersistentCoherentMapScenario.ThePushIsTheOnlyRouteAWriteTakesToTheServer`),不重跑 lane | 同上 | -| 17.5 | class-C verb 迁移(P5b) | 迁移顺序由动态普查决定;一次迁移 = 一个发射器 + 一个 sink 体;记录逐字带 GL 调用参数,未测量的形式按名拒绝(规则 D) | git 历史 | -| 17.6 | 共享地址空间访问归零(P5c) | server 端纹理 staged shadow;`SEG_EVENT` 是唯一反向通道;sink / twin 按记录句柄解析;`applier_reset` / `object_death` 控制记录;角色守卫 `Fatal{RoleViolation}` | git 历史 | -| 17.7 | run-ahead(P5e) | 规则 F:unbarriered 记录的 apply 不读任何 client 内存(违反即具名 Fatal,与 strict 开关无关);`gPipeInputs` 是 server 角色内存;`RunAheadArmed()` 在首次 caps 采纳时锁存,只能关不能开;`RUN_AHEAD=0` 是 A/B 对照 | git 历史 | +| 17.1 | verb barrier and honest same-address-space transport (P5) | The same address space must not become a bypass (R-2): the encoder always writes `nullptr` for `MGHostSpan::Ptr`; replies use the record sequence number as the slot id (R-3); the 120 s wait watchdog only judges deadlock, it is not a performance gate | git history | +| 17.2 | Three backend slot classes, caps, tight readback (P5) | A answers locally / B emits / C refuses by name, never falling back to the monolith (R-4); capabilities read only from `CallMask` (R-8); `ReadPixels` is always tight on the wire, and the client scatters by its own pack state | same as above | +| 17.3 | The server role, shadow and exit (P5) | The apply thread holds the native context for its lifetime; rare EGL operations enter the apply thread through the control mailbox; staged shadow only hands over server-owned copies; bounded exit order | same as above | +| 17.4 | lane isolation (P5) | Each split entry has a private log; the E1 vs E3(a) comparison is a permanent case (`RemoteWaitBoundaryControl.AnUnwaitedPublishIsSeenAsNoWait`, `PersistentCoherentMapScenario.ThePushIsTheOnlyRouteAWriteTakesToTheServer`), the lane is not rerun | same as above | +| 17.5 | class-C verb migration (P5b) | The migration order is decided by the dynamic census; one migration = one emitter + one sink body; records carry GL call arguments verbatim, and unmeasured forms are refused by name (rule D) | git history | +| 17.6 | Shared-address-space access reduced to zero (P5c) | Server-side texture staged shadow; `SEG_EVENT` is the only reverse channel; sink / twin resolve by record handle; `applier_reset` / `object_death` control records; role guard `Fatal{RoleViolation}` | git history | +| 17.7 | run-ahead (P5e) | Rule F: applying an unbarriered record reads no client memory (a violation is a named Fatal, independent of the strict switch); `gPipeInputs` is server-role memory; `RunAheadArmed()` latches at the first caps adoption and can only be turned off, not on; `RUN_AHEAD=0` is the A/B control | git history | diff --git a/docs/Disaggregated/design/11-state-ownership.md b/docs/Disaggregated/design/11-state-ownership.md index e721f84e..37099d0e 100644 --- a/docs/Disaggregated/design/11-state-ownership.md +++ b/docs/Disaggregated/design/11-state-ownership.md @@ -1,271 +1,271 @@ -# 状态归属:session / context / share group / thread current(P14 设计) +# State ownership: session / context / share group / thread current (P14 design) -> 为 anland 内置统一 server 而做。动因与否定项见 git 历史:不许用「每应用 fork 一个渲染进程」掩盖全局状态归属。本文行号对 `2f64ede8`(+ `4156ca6e` 文档提交),代码移动后以符号名检索。 +> Written for the unified server built into anland. The motivation and the rejected alternatives are in git history: "fork one render process per application" must not be used to paper over global state ownership. The line numbers here refer to `2f64ede8` (+ the `4156ca6e` documentation commit); after code moves, search by symbol name. -## 结论 +## Conclusion -今天整条栈的正确性建立在一个等式上:**一个进程 = 一个 server = 一个 session = 一个 context = 一个 share group**。`ServerLoopInstance`/`ServerSessionInstance`/`g_applyThreadKey`/`pGLContext`/`pEGLContext`/`g_Display`/`g_Context`/`g_Surface`/`g_applier`/`gMGPipeContext` 全是单实例。`2f64ede8` 的 `--serve --max-sessions` 用 fork 把等式搬进每个 worker 进程,绕开而不是解决归属;anland 统一 server 要求同进程多 session,等式必须在代码里真正拆开。 +Today the correctness of the whole stack rests on one equation: **one process = one server = one session = one context = one share group**. `ServerLoopInstance`/`ServerSessionInstance`/`g_applyThreadKey`/`pGLContext`/`pEGLContext`/`g_Display`/`g_Context`/`g_Surface`/`g_applier`/`gMGPipeContext` are all single-instance. `2f64ede8`'s `--serve --max-sessions` moves the equation into each worker process with fork, bypassing ownership instead of solving it; anland's unified server requires multiple sessions in one process, so the equation must actually be split apart in the code. -拆成四层归属: +Split into four ownership layers: -| 层 | 拥有什么 | 今天的错误位置 | +| Layer | What it owns | Where it is wrong today | |---|---|---| -| **Session** | SHM rings/segments、staged stores、reply/event 路由、failure、对象 handle 空间、PipeApplier、apply thread、backend runtime 绑定 | `ServerSessionInstance()`/`ServerLoopInstance()`/`g_applier` 单例(`ServerSession.cpp:535`、`ServerLoop.cpp:1191`、`PipeApply.cpp:484`) | -| **Context** | 独立 GLContext:bindings/render state/errors、VAO/FBO/TF/pipeline/query(容器对象不共享)、cache/scratch/owner/generation、native EGLContext | 唯一 `pGLContext`(`MG_State/GLState/Core.cpp:1565`);`eglCreateContext` 不建 GL 状态(`MG_State/EGLState/Core.cpp:625-700`);后端唯一 `g_Context`(`DirectGLES.cpp:16184`) | -| **Share group** | buffer/texture/renderbuffer/sampler/shader/program/sync 的对象 registry 与名称分配;后端 twin/native 对象映射 | 混在唯一 `pGLContext` 各 State 成员里(`MG_State/GLState/Core.h:610-692`);`shareCtx` 只存不用(`MG_State/EGLState/Core.cpp:650`) | -| **Thread current** | TLS 指向 (session, context);owner 关系不进 TLS,context 可跨线程移交;apply 显式设置 runtime scope | `m_threadCurrents`/`m_contextOwners` 已有雏形但绑死单实例表(`MG_State/EGLState/Core.h:283-284`);`g_applyThreadKey` 进程级(`ServerLoop.h:129`) | +| **Session** | SHM rings/segments, staged stores, reply/event routing, failure, the object handle space, PipeApplier, apply thread, backend runtime binding | The `ServerSessionInstance()`/`ServerLoopInstance()`/`g_applier` singletons (`ServerSession.cpp:535`, `ServerLoop.cpp:1191`, `PipeApply.cpp:484`) | +| **Context** | An independent GLContext: bindings/render state/errors, VAO/FBO/TF/pipeline/query (container objects are not shared), cache/scratch/owner/generation, native EGLContext | The single `pGLContext` (`MG_State/GLState/Core.cpp:1565`); `eglCreateContext` creates no GL state (`MG_State/EGLState/Core.cpp:625-700`); the backend's single `g_Context` (`DirectGLES.cpp:16184`) | +| **Share group** | The object registry and name allocation for buffer/texture/renderbuffer/sampler/shader/program/sync; the backend's twin/native object mapping | Mixed into the single `pGLContext`'s State members (`MG_State/GLState/Core.h:610-692`); `shareCtx` is stored but never used (`MG_State/EGLState/Core.cpp:650`) | +| **Thread current** | TLS points at (session, context); the owner relation does not go into TLS, a context can be handed over across threads; apply sets the runtime scope explicitly | `m_threadCurrents`/`m_contextOwners` already have a prototype but are tied to single-instance tables (`MG_State/EGLState/Core.h:283-284`); `g_applyThreadKey` is process-level (`ServerLoop.h:129`) | -关闭一个 session 不得破坏另一个;同名 handle 在不同 session/share group 互不干扰;shared contexts 看到同一份共享对象。 +Closing one session must not break another; the same handle name in different sessions/share groups must not interfere; shared contexts see the same shared objects. -## wire 变更 +## Wire changes -1. **逐记录 context 身份**。`MGPWireRecHeader` 8 B(`generated/PipeWire.inc:35-65`)不含身份;`MGPApplierReset::ContextSerial` 只做断言(`MGPipeTypes.h:1953-1960`)。设计:context 族记录(`PipeTables.inc:32-45` 的 71 个)在 header 与 payload 之间插入 `Uint32 ContextSlot`(flags 加 `kRecHasContext` 位,生成器在 `PipeCalls.def` 的族声明处统一加,不逐 verb 手改)。`ContextSlot=0` 保留给「session 默认 context」,兼容只有一个 context 的旧形状。screen 族记录操作的对象 handle 本身属 share group,server 经「记录所属 context → share group」解析,不另加字段。 - - 为什么不用「每 context 一条 ring」:ring 是 session 的资源/信用单位,每 context 一条会把 swap pacing、反向事件、segment 生命周期全部复制一份;逐记录身份 4 B 解决同一问题。 - - 交错正确性:多线程 client 的记录在一条 ring 上交错,apply 以记录自带的 context 为准,不得依赖「最后一个 MakeCurrent」。不可拆分批次(一次 emit 的多记录)同 context 才许合并,生成器在 batch 边界断言。 -2. **EGL 生命周期上 wire**。`eglCreateContext`/`eglDestroyContext` 今天是纯前端(`EGLImpl.cpp:327-333`、`:428-434`)。`SurfaceOpKind`(`protocol.fbs:240-267`)新增 `CreateContext{contextSlot, shareWithSlot, api, version, flags}` 与 `DestroyContext{contextSlot}`;`MakeCurrent` 的 `context` 字段从「恒 0/忽略」变成真实 slot。frontend 仍在本地建 EGL 元数据,wire 只负责让 server 建对应 native context 与 share group。 -3. **反向事件带 context**。`EventFenceSignaledHead`(`ServerSession.cpp:1324-1338`)、GL error、surface-changed 事件头加 `ContextSlot`(surface 事件已有 surface handle,context 便于 client 直接派发)。fence handle 属 context 的 share group,client 按 (slot, gen) 原样核对。 -4. **wireFingerprint 随以上变更 bump**;两端同 commit + 显式 `-DMOBILEGL_BUILD_STAMP=` 重建,不接受 drift(交接文档「构建产物」节)。 +1. **Per-record context identity**. `MGPWireRecHeader` 8 B (`generated/PipeWire.inc:35-65`) carries no identity; `MGPApplierReset::ContextSerial` only asserts (`MGPipeTypes.h:1953-1960`). Design: context-family records (the 71 in `PipeTables.inc:32-45`) insert `Uint32 ContextSlot` between the header and the payload (the flags gain a `kRecHasContext` bit; the generator adds it once at the family declaration in `PipeCalls.def`, not per verb by hand). `ContextSlot=0` is reserved for "the session's default context", compatible with the old shape that has only one context. For screen-family records the object handle they operate on itself belongs to the share group; the server resolves it through "the record's context → share group" and adds no separate field. + - Why not one ring per context: a ring is the session's resource/credit unit; one per context would duplicate swap pacing, reverse events and segment lifetime in full; per-record identity solves the same problem with 4 B. + - Interleaving correctness: records from a multi-threaded client interleave on one ring; apply follows the record's own context and must not rely on "the last MakeCurrent". An indivisible batch (several records from one emit) may be merged only if the records share a context; the generator asserts this at batch boundaries. +2. **EGL lifetime on the wire**. `eglCreateContext`/`eglDestroyContext` are pure frontend today (`EGLImpl.cpp:327-333`, `:428-434`). `SurfaceOpKind` (`protocol.fbs:240-267`) gains `CreateContext{contextSlot, shareWithSlot, api, version, flags}` and `DestroyContext{contextSlot}`; `MakeCurrent`'s `context` field goes from "always 0/ignored" to a real slot. The frontend still builds EGL metadata locally; the wire is only responsible for making the server create the corresponding native context and share group. +3. **Reverse events carry a context**. `EventFenceSignaledHead` (`ServerSession.cpp:1324-1338`), the GL error and surface-changed event headers gain `ContextSlot` (surface events already carry a surface handle; the context lets the client dispatch directly). A fence handle belongs to the context's share group; the client checks it verbatim by (slot, gen). +4. **wireFingerprint is bumped with the changes above**; both ends rebuild from the same commit + an explicit `-DMOBILEGL_BUILD_STAMP=`, and drift is not accepted (the "Build artifacts" section of the handover document). -## S1 已落地形状(context 身份上 wire) +## S1 landed shape (context identity on the wire) -上面第 1、2 条是 P14a 的目标形状;S1 只落地了「身份能跨线、server 能归属」这一层,实际形状如下,后续切片按此续建。 +Items 1 and 2 above are P14a's target shape; S1 landed only the layer "identity can cross the wire and the server can attribute it", with the actual shape below, and later slices continue from it. -**data plane:`bind_context`,opcode 84**(`MG_Pipe/PipeCalls.def`,`kScreen` 族)。 +**data plane: `bind_context`, opcode 84** (`MG_Pipe/PipeCalls.def`, the `kScreen` family). -| 项 | 值 | +| Item | Value | |---|---| -| payload | `MGPBindContext{ Uint64 ClientContextToken }`(8 B,`MGP_ASSERT_POD`) | -| flags / wait | `kNone` / `kWaitNone`(apply 不读客户端内存,记录的 ring 位置就是它的全部次序) | -| apply 入口 | 无 `MGPipeApply*`;与 `applier_reset`/`object_death` 同为 control record,只到 `WireVerbSink` | -| monolith 生产者 | 无(G1 不变) | -| sink | `ServerVerbSink::OnBindContext`(`MG_Remote/Server/PipeApplier.cpp`) | +| payload | `MGPBindContext{ Uint64 ClientContextToken }` (8 B, `MGP_ASSERT_POD`) | +| flags / wait | `kNone` / `kWaitNone` (apply reads no client memory; the record's ring position is its entire ordering) | +| apply entry | no `MGPipeApply*`; like `applier_reset`/`object_death` it is a control record and reaches only `WireVerbSink` | +| monolith producer | none (G1 unchanged) | +| sink | `ServerVerbSink::OnBindContext` (`MG_Remote/Server/PipeApplier.cpp`) | -**token 位宽:两端都是 `Uint64`。** 记录里是 `ClientContextToken`,控制帧里是 `SurfaceOp.context`;同宽是刻意的,否则必有一端要截断。`0` 在两处都表示「无 context」(release),也正是一个从未 bind 过的 session 已有的答案。token 由 `EGLState::CreateContext` 铸造(`m_nextClientContextToken` 从 1 起、稠密、不复用),随 `ContextObject` 存放,`EGLState::CurrentContextClientToken()` / `GetContextClientToken()` 读出。 +**token width: `Uint64` on both ends.** In the record it is `ClientContextToken`, in the control frame it is `SurfaceOp.context`; the equal width is deliberate, otherwise one end would have to truncate. `0` means "no context" (release) in both places, which is also the answer a session that has never bound already has. The token is minted by `EGLState::CreateContext` (`m_nextClientContextToken` starts at 1, dense, never reused), stored with `ContextObject`, and read out by `EGLState::CurrentContextClientToken()` / `GetContextClientToken()`. -**control plane:`SurfaceOpKind.CreateContext = 12` / `DestroyContext = 13`**(`protocol.fbs`),不是两个新的 CtrlMsg——context 的创建/销毁/make-current 与 surface 是同一个调用者、同一个线程、同一条阻塞 frame channel,另开一条只会多一个次序会打架的地方。`SurfaceOp` 追加 `shareGroupToken: ulong` 与 `contextFlags: uint`(保留扩展位,今天恒 0)。`MOBILEGL_PROTOCOL_CONTROL_REVISION` 5 → 6,`scripts/ci/protocol_revision_pins.json` 同步加行。 +**control plane: `SurfaceOpKind.CreateContext = 12` / `DestroyContext = 13`** (`protocol.fbs`), not two new CtrlMsgs—creating, destroying and make-current of a context have the same caller, the same thread and the same blocking frame channel as a surface, and opening another one would only add another place where ordering fights. `SurfaceOp` appends `shareGroupToken: ulong` and `contextFlags: uint` (reserved for extension, always 0 today). `MOBILEGL_PROTOCOL_CONTROL_REVISION` 5 → 6, with the line added to `scripts/ci/protocol_revision_pins.json` in sync. -- `CreateContext`:`context` = 新 context 的 token,`shareGroupToken` = 它并入的 share group(`shareCtx` 的族,或新建),`contextFlags` = 保留位。`display`/`surface` 为 0(server 的 display 就是 session 自己的)。 -- `DestroyContext`:`context` = 要销的 token;server 销表并在它当前 bind 时解绑。 -- 两者都用既有的 `SurfaceReply` 回答(ok + refusal),S1 建的是占位 runtime,没有别的可回。 +- `CreateContext`: `context` = the new context's token, `shareGroupToken` = the share group it joins (`shareCtx`'s family, or a new one), `contextFlags` = reserved bits. `display`/`surface` are 0 (the server's display is the session's own). +- `DestroyContext`: `context` = the token to destroy; the server removes the entry and unbinds it if it is currently bound. +- Both are answered with the existing `SurfaceReply` (ok + refusal); S1 builds a placeholder runtime and has nothing else to reply with. -**`bind_context` 与 MakeCurrent 控制帧的关系:不合并,各管一件事。** +**Relationship between `bind_context` and the MakeCurrent control frame: not merged, each handles one thing.** -- `MakeCurrent` 控制帧仍是 **native tuple 的 op**:它让 server 的 apply thread 决定要不要真的 `eglMakeCurrent`,并参与 `m_haveCurrentTuple` 的去重(ID-54/ID-67 的口径一个字没动)。它的 `context` 字段与 `bind_context` 的 token 是同一个值,但那是「同一个身份」,不是「同一条通路」。 -- `bind_context` 是 **ring 上的归属记录**:它告诉 server「这条 ring 上从今往后的记录属于哪个 context」。它必须在 ring 上,因为 GL 记录就在 ring 上,而控制帧与 ring 之间没有全局次序可依赖。 -- 发射点只有一个:`EGLImpl::MakeCurrent` 在切换成功之后、返回之前调 `EmitContextBinding`(`MG_Impl/EGLImpl/EGLImpl.cpp`)。这给出「先于后续 GL 记录」的构造性保证——app 线程在 `eglMakeCurrent` 返回前不可能发出新 context 的任何记录,而 ring 是 FIFO。token 未变则不发(identical make-current 是 EGL 合法 no-op)。 -- `DestroyContext` 帧在客户端 `EGLState::DestroyContext` 接受之后才发,所以 EGL 自己拒掉的那种销毁(context 仍被某线程 current)不会到达 server,两端不会因为「token 悄悄消失」而对不上。 +- The `MakeCurrent` control frame is still an **op on the native tuple**: it lets the server's apply thread decide whether to actually `eglMakeCurrent`, and takes part in `m_haveCurrentTuple` deduplication (the ID-54/ID-67 wording is untouched by a single character). Its `context` field is the same value as `bind_context`'s token, but that is "the same identity", not "the same path". +- `bind_context` is an **ownership record on the ring**: it tells the server "the records from now on, on this ring, belong to which context". It must be on the ring because GL records are on the ring, and there is no global order between a control frame and the ring to rely on. +- There is exactly one emission point: `EGLImpl::MakeCurrent` calls `EmitContextBinding` (`MG_Impl/EGLImpl/EGLImpl.cpp`) after the switch succeeds and before returning. That gives the constructive guarantee "before any later GL record"—the app thread cannot emit any record for the new context before `eglMakeCurrent` returns, and the ring is FIFO. If the token is unchanged nothing is emitted (an identical make-current is a legal EGL no-op). +- The `DestroyContext` frame is sent only after the client's `EGLState::DestroyContext` accepts, so a destroy that EGL itself refuses (the context is still current on some thread) never reaches the server, and the two ends cannot disagree through "the token quietly vanished". -**与第 1 条的取舍差异(明确记录)**:S1 走的是「在边沿宣告身份」而不是「在 71 个 context 族记录的 header 与 payload 之间插 `Uint32 ContextSlot`」。代价是每个 make-current 一条记录(而不是每条记录 4 B),收益是 payload 布局与 `MGPWireRec_*` 尺寸全部不动、`kRecHasContext` 位与 batch 边界的生成器改动全部不必;单 context 的既有形状(token 0 / 从未 bind 过)零改动即兼容。多线程交错下的逐记录身份若将来确有需要,再按第 1 条补 slot——那时两者可以并存,slot 为 0 仍读当前 token。 +**Difference in trade-off from item 1 (recorded explicitly)**: S1 takes "announce the identity at the edge" instead of "insert `Uint32 ContextSlot` between the header and payload of the 71 context-family records". The cost is one record per make-current (instead of 4 B per record); the benefit is that the payload layout and every `MGPWireRec_*` size stay unchanged, and the `kRecHasContext` bit and the batch-boundary generator changes are all unnecessary; the existing single-context shape (token 0 / never bound) is compatible with zero changes. If per-record identity under multi-thread interleaving really is needed later, add the slot per item 1 then—the two can coexist, and slot 0 still reads the current token. -**server 端**(`MG_Remote/Server/ServerSession.{h,cpp}`):每 session 一张 `{token → ContextRuntime}`(`ContextRuntime{ Token, ShareGroupToken, Flags }`,S1 里是占位,S4 给它装 native context)加一个当前 token(atomic,0 = 无)。`CreateContext`/`DestroyContext` 控制帧经 `ServerLoop::ApplySurfaceControlFrame` 的 `CreateContext`/`DestroyContext` 两个 arm 建表/销表;`bind_context` 经 codec 到 `ServerVerbSink::OnBindContext` 切当前 token。写入全部发生在 apply thread,表因此不需要锁。`bind_context` 指向一个本 session 从未创建的 token 是 `Fatal{ProtocolCorruption, "BindContext.ClientContextToken"}`(0 例外,永远合法);表的存在正是为了让这条判定有依据。 +**Server side** (`MG_Remote/Server/ServerSession.{h,cpp}`): each session gets a `{token → ContextRuntime}` table (`ContextRuntime{ Token, ShareGroupToken, Flags }`, a placeholder in S1, S4 gives it a native context) plus a current token (atomic, 0 = none). The `CreateContext`/`DestroyContext` control frames create/destroy the table through the `CreateContext`/`DestroyContext` arms of `ServerLoop::ApplySurfaceControlFrame`; `bind_context` goes through the codec to `ServerVerbSink::OnBindContext` to switch the current token. All writes happen on the apply thread, so the table needs no lock. A `bind_context` pointing at a token this session never created is `Fatal{ProtocolCorruption, "BindContext.ClientContextToken"}` (0 excepted, always legal); the table exists precisely so that this ruling has a basis. -**S1 的 token 只有写入者,没有读者**:server 端目前没有任何 apply 分支读 `CurrentContextToken()`(`grep` 可证:除 `ServerSession` 自己的访问器外无人调用),所以整条渲染路径的行为与 S1 之前逐字相同——这一层先把「归属」记下来,读它做事是 S4(native context)和 P14b/c 的事。没有 `bind_context` 的 session 行为同样不变:`ServerLoopTest` 的 MakeCurrent/epoch/liveness 用例(`MG_Test/Wire/ServerLoopTest.cpp:1780-1941`)仍全部通过,它们走的正是这条路径。 +**S1's token has a writer but no readers**: no apply branch on the server reads `CurrentContextToken()` today (provable by `grep`: nothing outside `ServerSession`'s own accessor calls it), so the whole rendering path behaves character for character as before S1—this layer records ownership first; reading it to act is S4's job (native context) and P14b/c's. A session without `bind_context` behaves identically too: the `ServerLoopTest` MakeCurrent/epoch/liveness cases (`MG_Test/Wire/ServerLoopTest.cpp:1780-1941`) all still pass, and they go through exactly this path. -**S1 的验收证据**(本次提交的测试):`PipeCatalogue.LateArrivalsAreAppendedWithoutRenumbering` 钉 opcode 84 与 `kNone`/`kScreen`/`kWaitNone`;`SurfaceControlFrameTest.TheContextLifecycleFramedOpsAreCreateContextAndDestroyContext` 钉 12/13 的值与 `shareGroupToken`/`contextFlags` 的往返;`SessionHandshakeTest.ARevisionFivePeerIsRefusedByNameAtRevisionSix` 钉 revision bump;`FuzzArm2/PeerLatchSite/.../BindContextUnknownToken` 是 data plane 的端到端控制——真实 `--serve` supervisor 上,一个伪造的、指向本 session 从未创建过的 token 的 `bind_context` 让 session 按名 latch(`exit=75`),且同一 supervisor 的下一个 session 正常渲染。 +**S1's acceptance evidence** (the tests of this commit): `PipeCatalogue.LateArrivalsAreAppendedWithoutRenumbering` pins opcode 84 and `kNone`/`kScreen`/`kWaitNone`; `SurfaceControlFrameTest.TheContextLifecycleFramedOpsAreCreateContextAndDestroyContext` pins the values 12/13 and the `shareGroupToken`/`contextFlags` round trip; `SessionHandshakeTest.ARevisionFivePeerIsRefusedByNameAtRevisionSix` pins the revision bump; `FuzzArm2/PeerLatchSite/.../BindContextUnknownToken` is the data-plane end-to-end control—on a real `--serve` supervisor, a forged `bind_context` that points at a token this session never created makes the session latch by name (`exit=75`), and the next session of the same supervisor renders normally. -## 前端(MG_State / MG_Impl) +## Frontend (MG_State / MG_Impl) -1. **拆 GLContext**。`MG_State/GLState/Core.h:77-698` 的 `GLContext` 拆成 `ShareGroupState`(buffer/texture/renderbuffer/sampler/shader/program/sync 的对象 store + 名称分配)与 `GLContext`(bindings、error、viewport/scissor、render state、VAO/FBO/TF/pipeline/query store、texture unit 绑定、current program)。容器对象(VAO/FBO/TF/pipeline/query)**不共享**,留在 per-context;这是 GL 4.6 §5 的口径,不要为省事把 FBO 放进 share group。 -2. **per-EGLContext 实例化**。`EGLState::CreateContext` 建 `GLContext`,`shareCtx != EGL_NO_CONTEXT` 时挂到对方 `ShareGroupState`(首次共享时把对方的对象 store 迁移进新 share group,双方同指)。`eglMakeCurrent` 切 TLS 的 (session→) GLContext 指针;`eglDestroyContext` 只在 owner 不存在时允许(沿用 `MG_State/EGLState/Core.cpp:714-718`),销毁 context 不销毁 share group,最后一个 context 离开时 share group 对象全删。 -3. **Tracker 判据改显式身份**。`Pipe/Tracker.h:306-309` 的指针比较换成 (session, contextSlot);换 context 的首个 verb 重推完整状态的语义不变。`MGPipeTrackerInstance()`(`Tracker.h:956-963`)从单例改为 per-context(tracker 缓存的是 per-context 推送快门)。 -4. **eglMakeCurrent 流程**:`EGLImpl::MakeCurrent` 除调 `backendObject->MakeEGLCurrent` 外,先切 TLS GLContext 再发 `SurfaceOp::MakeCurrent{contextSlot}`;client 线程后续的 context 族记录都带这个 slot。 +1. **Split GLContext**. `MG_State/GLState/Core.h:77-698`'s `GLContext` splits into `ShareGroupState` (the object store + name allocation for buffer/texture/renderbuffer/sampler/shader/program/sync) and `GLContext` (bindings, error, viewport/scissor, render state, VAO/FBO/TF/pipeline/query store, texture unit bindings, current program). Container objects (VAO/FBO/TF/pipeline/query) are **not shared** and stay per-context; that is the GL 4.6 §5 wording—do not put FBO into the share group for convenience. +2. **Per-EGLContext instantiation**. `EGLState::CreateContext` creates a `GLContext`; when `shareCtx != EGL_NO_CONTEXT` it attaches to the other side's `ShareGroupState` (at the first share, migrate the other side's object store into the new share group, both pointing at it). `eglMakeCurrent` switches the TLS (session→) GLContext pointer; `eglDestroyContext` is allowed only when no owner exists (following `MG_State/EGLState/Core.cpp:714-718`); destroying a context does not destroy the share group, and when the last context leaves all share group objects are deleted. +3. **The tracker criterion becomes explicit identity**. The pointer comparison in `Pipe/Tracker.h:306-309` becomes (session, contextSlot); the semantics of re-pushing the full state on the first verb after a context switch are unchanged. `MGPipeTrackerInstance()` (`Tracker.h:956-963`) goes from a singleton to per-context (the tracker caches the per-context push shutter). +4. **eglMakeCurrent flow**: besides calling `backendObject->MakeEGLCurrent`, `EGLImpl::MakeCurrent` first switches the TLS GLContext and then sends `SurfaceOp::MakeCurrent{contextSlot}`; later context-family records from the client thread all carry this slot. -## S3 已落地形状(前端 per-context / share group) +## S3 landed shape (frontend per-context / share group) -上面「前端」一节是目标形状;S3 落地了第 1、2 条(第 3、4 条的 tracker/slot 部分未做),实际形状如下。 +The "Frontend" section above is the target shape; S3 landed items 1 and 2 (the tracker/slot parts of items 3 and 4 are not done), and the actual shape is below. -**`ShareGroupState`(`MG_State/GLState/ShareGroupState.{h,cpp}`,新)** 持有一个 share group 的全部对象注册表与名字生成器: +**`ShareGroupState` (`MG_State/GLState/ShareGroupState.{h,cpp}`, new)** holds all object registries and name generators of one share group: -| 共享(ShareGroupState) | 每 context(GLContext) | +| Shared (ShareGroupState) | Per context (GLContext) | |---|---| -| buffer / texture / renderbuffer 的对象表与 `IndexGenerator`;sampler 对象表(`SamplerState` 整体);program+shader 表与共用名字生成器(`ProgramState` 整体);`token`(S1 的 `ShareGroupToken`) | error 列表;buffer binding slot 与 indexed binding point、touched 高水位、各 aggregate generation;texture unit / image unit 数组、active unit、bind/sampling generation、per-target 默认纹理(name 0);renderbuffer binding slot;VAO/FBO/TF/pipeline/query;`current program` | +| The object tables and `IndexGenerator` for buffer / texture / renderbuffer; the sampler object table (all of `SamplerState`); the program+shader tables and the shared name generator (all of `ProgramState`); `token` (S1's `ShareGroupToken`) | The error list; buffer binding slots and indexed binding points, touched high-water marks, the per-aggregate generations; texture unit / image unit arrays, the active unit, bind/sampling generation, the per-target default texture (name 0); renderbuffer binding slots; VAO/FBO/TF/pipeline/query; `current program` | -`BufferState`/`TextureState`/`RenderbufferState` 因此只剩 binding 侧:删除走「先查 share group 的对象、再解本 context 的绑定、最后 free 名字」,即删对象是全局的、解绑定是逐 context 的(GL 4.6 core 6.1/8.1)。`ProgramState` 的 `UseProgram`/`glDeleteProgram`/`ReleaseShaderNameIfOrphaned` 现在把调用方的 current program 当参数传入,current program 本身落在 `GLContext`。`GLContext` 由 `GLContext(SharedPtr)` 构造,`GLContext()` 建一个只属于它的 share group(测试与进程默认 context 用)。 +`BufferState`/`TextureState`/`RenderbufferState` therefore keep only the binding side: deletion goes "first look up the share group's object, then unbind this context, finally free the name", i.e. deleting an object is global and unbinding is per-context (GL 4.6 core 6.1/8.1). `ProgramState`'s `UseProgram`/`glDeleteProgram`/`ReleaseShaderNameIfOrphaned` now take the caller's current program as a parameter, and the current program itself lives in `GLContext`. `GLContext` is constructed from `GLContext(SharedPtr)`; `GLContext()` creates a share group that belongs only to it (used by tests and the process default context). -**`pGLContext` 改成 TLS**:`extern thread_local SharedPtr pGLContext`(`GLState/Core.h`)。`EGLState::MakeCurrent` 成功后把它指向该 context 的 `GLContext`,`ReleaseThread`/`eglTerminate`/释放路径恢复线程进入 EGL 之前的那个值(`ThreadCurrentState::RestoreThreadGLState`)——所以「一个 context 同时只被一个线程拥有」的既有语义(`m_contextOwners`,EGL_BAD_ACCESS)一个字没动,owner 也不进 TLS:context 跨线程移交后状态仍在它自己的 `GLContext` 里。 +**`pGLContext` becomes TLS**: `extern thread_local SharedPtr pGLContext` (`GLState/Core.h`). After `EGLState::MakeCurrent` succeeds it points at that context's `GLContext`; `ReleaseThread`/`eglTerminate`/the release path restore the value the thread had before entering EGL (`ThreadCurrentState::RestoreThreadGLState`)—so the existing semantics "one context is owned by one thread at a time" (`m_contextOwners`, EGL_BAD_ACCESS) are untouched by a single character, and the owner does not go into TLS either: after a context is handed over across threads its state is still in its own `GLContext`. -没有 EGL context 的线程落到**进程默认 context**(`ProcessDefaultGLContext()`,`MG_State::Init()` 建,构造时 `pGLContext` 的初值就是它)——这正是拆分前「全局唯一 context」的语义,所以单 context 应用与所有直接操作 `pGLContext` 的既有测试行为不变。 +A thread without an EGL context falls to the **process default context** (`ProcessDefaultGLContext()`, created by `MG_State::Init()`; `pGLContext` is initialized to it at construction)—this is exactly the pre-split "one global context" semantics, so single-context applications and all existing tests that operate on `pGLContext` directly behave unchanged. -**每个 `eglCreateContext` 都建独立 `GLContext`**(`ContextObject::GLStateObject`);`shareCtx != EGL_NO_CONTEXT` 时 `GLContext` 挂到对方 `ShareGroupState`,否则新建一个并把 S1 铸的 `ShareGroupToken` 记在里面。这里不需要「迁移对方 store」:group 在第一个 context 诞生时就存在,后来者直接并入。`eglDestroyContext` 丢掉 `ContextObject`,共享指针归零才销毁 `GLContext` / `ShareGroupState`。 +**Every `eglCreateContext` creates an independent `GLContext`** (`ContextObject::GLStateObject`); when `shareCtx != EGL_NO_CONTEXT`, the `GLContext` attaches to the other side's `ShareGroupState`, otherwise it creates a new one and records the `ShareGroupToken` minted in S1 in it. There is no need here to "migrate the other side's store": the group exists when the first context is born, and later ones simply join. `eglDestroyContext` drops the `ContextObject`; `GLContext` / `ShareGroupState` are destroyed when the shared pointer reaches zero. -**默认帧缓冲(明确的偏差)**:GL framebuffer 0 今天仍是**进程一个对象**(`MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo`,后端按它判断「这是默认 FBO」)。它在 `MG_Impl::Init()` 建好之后经 `MG_State::SetDefaultFramebuffer` 交给 MG_State,此后每个新建 `GLContext` 构造时把它装成自己的 name 0 并绑到 Draw/Read(`GLContext::InstallDefaultFramebuffer`)。也就是说:每个 context 有**自己的 FramebufferState 表项与绑定**(`glBindFramebuffer` 互不影响),但那个对象暂时是共用的。真正的 per-context 默认帧缓冲属于「后端 per-context native tuple」那一期(见「后端」§1),在那之前若各 context 各建一份,后端的 `pDefaultFramebufferInfo` 身份判定会对第二个 context 失效。 +**The default framebuffer (an explicit deviation)**: GL framebuffer 0 is still **one object per process** today (`MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo`; the backend uses it to decide "this is the default FBO"). It is handed to MG_State through `MG_State::SetDefaultFramebuffer` after `MG_Impl::Init()` creates it; after that every newly constructed `GLContext` installs it as its own name 0 and binds it to Draw/Read (`GLContext::InstallDefaultFramebuffer`). That is: every context has **its own FramebufferState entry and binding** (`glBindFramebuffer` calls do not affect each other), but the object is shared for now. A real per-context default framebuffer belongs to the "backend per-context native tuple" phase (see "Backend" §1); until then, if each context created its own, the backend's `pDefaultFramebufferInfo` identity test would fail for the second context. -**monolith 与 split 走同一份结构**:两端共用一个 `MG_State`,`eglCreateContext`/`eglMakeCurrent`/`eglDestroyContext` 都先落这套前端状态,`MOBILEGL_PIPE_PUSH=0` 与 `=1` 的区别只是后端从哪儿读状态(`MGB_CTX` 是 `pGLContext` 还是 `gPipeInputs`)。`MGB_CTX_IDENTITY` 因此天然按 context 变化,post-S3 的 tracker 只需照旧比较(改成显式 slot 是后续切片)。 +**Monolith and split use the same structure**: both ends share one `MG_State`; `eglCreateContext`/`eglMakeCurrent`/`eglDestroyContext` all write this frontend state first, and the only difference between `MOBILEGL_PIPE_PUSH=0` and `=1` is where the backend reads state from (`MGB_CTX` is either `pGLContext` or `gPipeInputs`). `MGB_CTX_IDENTITY` therefore naturally varies per context, and the post-S3 tracker only has to compare as before (turning it into an explicit slot is a later slice). -**验收证据**(本次):`MG_Test/State/ContextStateOwnershipTest.cpp` 六个用例——不共享的两个 context 名字空间独立(同名不同对象、绑定不互见);共享对看到同一对象而各自持有绑定;`eglMakeCurrent` 切换后 error/viewport/FBO binding 各自独立且切回来还在;`eglDestroyContext` 后另一个 context 对象与绑定不受影响;释放后线程回到进入 EGL 前的 GL 状态;无 current context 的线程落到进程默认 context。 +**Acceptance evidence** (this commit): six cases in `MG_Test/State/ContextStateOwnershipTest.cpp`—two nonshared contexts have independent name spaces (same name, different objects, bindings not visible to each other); a shared pair sees the same object while each holds its own bindings; after an `eglMakeCurrent` switch, error/viewport/FBO binding are independent and still there when switching back; after `eglDestroyContext` the other context's objects and bindings are unaffected; after release the thread returns to the GL state it had before entering EGL; a thread without a current context falls to the process default context. -## server(MG_Remote/Server) +## Server (MG_Remote/Server) -1. **session registry 取代单例**。`ServerSessionInstance`/`ServerLoopInstance` 改为 `ServerProcess` 持有的 session 表(slot → {transport, ServerSession, ServerLoop, PipeApplier, apply thread})。in-process server(`ServerMain.cpp:1593-1651` 的 `mobilegl_server_serve_inprocess`)从「单 active + RefuseBusy」改为接受至上限(默认 8,可配);`--serve` 的 unix 路径同样改为同进程多 session,**移除 fork-worker 分发**(`ServerMain.cpp:1566-1584`),`--max-sessions` 语义改为同进程上限。TCP 的 `TcpSupervisor` 单 active(`:1220-1223`)同样让位。 -2. **apply thread per session**。每 session 一个 apply thread;`g_applyThreadKey`(`ServerLoop.h:129`)改为 per-session 成员,`OnApplyThread()` 语义不变(同 thread 比较)。session 之间顺序调度由线程天然完成,不需要全局锁;native driver 本来就支持多线程各自 current 不同 context。 -3. **g_applier per session**。`PipeApply.cpp:484` 的进程级 `MGPipeApplierState` 改为 session 持有;`MGPipeApplierReset` 的 role guard(`PipeApply.cpp:1474-1481`)按本 session 的 apply thread 判定。`PipeApply.h:558-617` 已有的 share-group 对象记录 / working-state 二分是地基:对象记录表按 share group 分桶,working state 按 context 分桶,reset 只清本 context 的 working state。**(S5 已落地,形状见下面「S5 已落地形状」:这一条最终不是「per session 一个 applier」,而是 per {session, context} 一个 applier、其对象记录挂到 {session, shareGroup} 的组上。)** -4. **反向路由按 session + context**。`ReverseCallbackOwner`(`ServerSession.cpp:408-418`)的 `Active()` 单活性改为「按发起线程/显式 session 参数解析」;事件头加 `ContextSlot`(见 wire 3)。`gMGPipeCallbacks`(`MGPipeCallbacks.h:77`)从进程级变量改为 per-session 表,Accept 时挂到 session 而非全局。 -5. **session 模式闩保留在 session 层**。`SessionSurfaceMode`/`SurfaceModeMismatch`(`ServerLoop.h:199-206`、`ServerLoop.cpp:1539-1544`)口径不变:compositor session 闩 OnScreen、app session 闩 Offscreen;统一 server 同时持有两种 session 是合法形状,不许把闩提升到进程级。 +1. **Session registry replaces the singletons**. `ServerSessionInstance`/`ServerLoopInstance` become a session table held by `ServerProcess` (slot → {transport, ServerSession, ServerLoop, PipeApplier, apply thread}). The in-process server (`ServerMain.cpp:1593-1651`'s `mobilegl_server_serve_inprocess`) goes from "single active + RefuseBusy" to accepting up to a limit (default 8, configurable); the unix path of `--serve` likewise becomes multiple sessions in the same process, **removing fork-worker dispatch** (`ServerMain.cpp:1566-1584`), and `--max-sessions` becomes the same-process limit. TCP's single-active `TcpSupervisor` (`:1220-1223`) gives way as well. +2. **One apply thread per session**. `g_applyThreadKey` (`ServerLoop.h:129`) becomes a per-session member; `OnApplyThread()` semantics unchanged (same-thread comparison). Ordering between sessions is naturally done by the threads, with no global lock; the native driver already supports multiple threads each current with a different context. +3. **`g_applier` per session**. The process-level `MGPipeApplierState` in `PipeApply.cpp:484` becomes session-owned; `MGPipeApplierReset`'s role guard (`PipeApply.cpp:1474-1481`) judges by this session's apply thread. The existing share-group object records / working-state split in `PipeApply.h:558-617` is the foundation: object record tables are bucketed by share group, working state by context, and reset clears only this context's working state. **(S5 has landed; for the shape see "S5 landed shape" below: this item ultimately is not "one applier per session" but one applier per {session, context}, whose object records hang on the {session, shareGroup} group.)** +4. **Reverse routing by session + context**. `ReverseCallbackOwner`'s (`ServerSession.cpp:408-418`) single-activity `Active()` becomes "resolve by the originating thread / an explicit session parameter"; event headers gain `ContextSlot` (see wire 3). `gMGPipeCallbacks` (`MGPipeCallbacks.h:77`) goes from a process-level variable to a per-session table, attached to the session at Accept rather than globally. +5. **The session mode latch stays at the session layer**. `SessionSurfaceMode`/`SurfaceModeMismatch` (`ServerLoop.h:199-206`, `ServerLoop.cpp:1539-1544`) keep their wording: a compositor session latches OnScreen, an app session latches Offscreen; a unified server holding both kinds of session at once is a legal shape, and the latch must not be raised to process level. -### S2 已落地形状(同进程多 session) +### S2 landed shape (multiple sessions in one process) -上面第 1、2、4、5 条是 P14c 的目标形状;本切片落地的是「归属拆开、路由按线程」这一层,实际形状如下。 +Items 1, 2, 4 and 5 above are P14c's target shape; this slice landed the layer "ownership split, routing by thread", and the actual shape is below. -**每 session 一个 runtime,singleton 变成 fallback**(`MG_Remote/Server/SessionRuntime.h`)。`SessionRuntime` 持有该 session 的 `ServerSession`、`ServerLoop`、`PipeInputs` 块,加一个 latch domain 与一个 segment resolver 绑定;`ThreadSessionScope` 把它挂到 **该 session 的两个线程**上——控制线程(`ServerMain::RunSession` 自己的线程,supervisor 里每 session 一条 `std::thread`)与 apply 线程(`mgl-srv-apply`,`ApplyThreadMain` 第一件事就是开同一个 scope)。`ServerSessionInstance()` / `ServerLoopInstance()` / `ServerSession::Active()` 因此先问「本线程属于哪个 session」,只有**不属于任何 session 的线程**才拿进程级单例。这一条让 ~900 个 `gPipeInputs` / `MGB_CTX` / `ServerSession::Active()` 调用点一行不改就有正确归属。inproc 的「同进程 client+server」形状刻意不开 scope(`ClientSession` 直接调单例),所以那个形状的 verb barrier、单块 PipeInputs 与逐字行为完全不变。 +**One runtime per session, the singleton becomes a fallback** (`MG_Remote/Server/SessionRuntime.h`). `SessionRuntime` holds the session's `ServerSession`, `ServerLoop` and `PipeInputs` block, plus a latch domain and a segment resolver binding; `ThreadSessionScope` attaches it to **the session's two threads**—the control thread (`ServerMain::RunSession`'s own thread, one `std::thread` per session in the supervisor) and the apply thread (`mgl-srv-apply`, whose first act in `ApplyThreadMain` is to open the same scope). `ServerSessionInstance()` / `ServerLoopInstance()` / `ServerSession::Active()` therefore first ask "which session does this thread belong to", and only **a thread that belongs to no session** gets the process-level singleton. This item gives ~900 `gPipeInputs` / `MGB_CTX` / `ServerSession::Active()` call sites correct attribution without changing a line. The inproc "client+server in one process" shape deliberately does not open a scope (`ClientSession` calls the singleton directly), so that shape's verb barrier, single PipeInputs block and character-for-character behavior are completely unchanged. -**gPipeInputs 是每线程解析的引用**(`MG_Backend/MGPipe/PipeInputs.h`)。`gPipeInputs` 从「一个进程级对象」变成 `thread_local` 引用,经 `g_pipeInputsThreadResolver` 这个由 server 层装一次的探针解析到本线程 session 的块,无 session 时落到 `gPipeInputsDefault`(即原对象)。**为什么是这个形状**:`MGB_CTX` 是 `(&gPipeInputs)`,要让 ~380 个点位不动而目标随线程变,只有「目标随线程变的引用」可行。代价是每个访问点一次 TLS 地址计算(不是每个字段,且无 guard:每线程第一次使用时绑定一次),这是本切片的已知成本。 +**`gPipeInputs` is a per-thread resolved reference** (`MG_Backend/MGPipe/PipeInputs.h`). `gPipeInputs` goes from "one process-level object" to a `thread_local` reference, resolved through `g_pipeInputsThreadResolver`, a probe the server layer installs once, to this thread's session's block, falling back to `gPipeInputsDefault` (the original object) when there is no session. **Why this shape**: `MGB_CTX` is `(&gPipeInputs)`; to leave ~380 sites unchanged while making the target vary by thread, only "a reference whose target varies by thread" works. The cost is one TLS address computation per access site (not per field, and with no guard: bound once on first use per thread), which is this slice's known cost. -**apply 线程身份改成 TLS 一位,进程级那个字改成计数。** `OnApplyThread()` 的答案现在只可能是「本线程是不是 apply 线程」,所以它是 `thread_local Bool`(零初始化,无 guard、无原子);`Detail::g_applyThreadKey` 保留原名与类型但装的是**本进程活着的 apply 线程数**——`MG_Backend/DirectGLES/Managers.cpp`(本切片文件集之外)读这个 `!= 0` 问「有没有 apply 线程在跑」,计数正好回答那个问题,热路径没有人再读它。 +**The apply-thread identity becomes one TLS bit; the process-level word becomes a counter.** `OnApplyThread()`'s answer can now only be "is this thread an apply thread", so it is a `thread_local Bool` (zero-initialized, no guard, no atomic); `Detail::g_applyThreadKey` keeps its name and type but holds **the number of live apply threads in this process**—`MG_Backend/DirectGLES/Managers.cpp` (outside this slice's file set) reads `!= 0` to ask "is any apply thread running", and the count answers exactly that; no hot path reads it anymore. -**latch 是每 session 一个 domain**(`MG_Remote/FatalFunnel.*`)。原来的四个进程级静态变量变成按 domain 存的 `LatchState`,线程绑定一个 domain(`ThreadSessionScope`),不绑定就是 domain 0(进程默认 = 老行为)。理由不是整洁而是正确性:`SessionLatched()` 的三个读者都在 session 自己的线程上(apply 循环、`DrainRing`、`RunSession` 的控制循环),一个进程共用一个 latch 时 session A 的坏字节能停掉 B 的 apply 线程;`ResetSessionLatch()` 也有镜像问题(一个 session 的 reap 会清掉活着的那个的 latch)。现在 A 的关闭/故障都到不了 B。 +**The latch is one domain per session** (`MG_Remote/FatalFunnel.*`). The original four process-level statics become per-domain `LatchState`; a thread binds to a domain (`ThreadSessionScope`), and without a binding it is domain 0 (the process default = the old behavior). The reason is correctness, not tidiness: all three readers of `SessionLatched()` are on the session's own threads (the apply loop, `DrainRing`, `RunSession`'s control loop), and when one latch is shared by the process a bad byte in session A can stop B's apply thread; `ResetSessionLatch()` has the mirror problem (one session's reap clearing the live one's latch). Now A's close/fault cannot reach B. -**segment resolver 是每线程的表 + 进程级的 hook**(`MG_Remote/Wire/PipeWireCodec.*`)。`gMGPipeSegmentResolver` 仍是一个进程级函数指针(装一次,不再置空),但 thunk 先查**调用线程绑定的表**,其次才是进程级 fallback。同一线程上出现第二张表仍然是 `Fatal{...already installed...}`(既有 `APartiallyZeroUploadBoxIsFatalRatherThanASilentRace` 与 `ASecondProcessResolverIsFatalRatherThanASilentRace` 的口径不变);不同线程上的第二个 session 不再是错误。 +**The segment resolver is a per-thread table plus a process-level hook** (`MG_Remote/Wire/PipeWireCodec.*`). `gMGPipeSegmentResolver` remains a process-level function pointer (installed once, never cleared again), but the thunk first checks **the calling thread's bound table**, and only then the process-level fallback. A second table on the same thread is still `Fatal{...already installed...}` (the wording of the existing `APartiallyZeroUploadBoxIsFatalRatherThanASilentRace` and `ASecondProcessResolverIsFatalRatherThanASilentRace` is unchanged); a second session on a different thread is no longer an error. -**全局回调表:装一次、按线程路由、最后一个 session 关才卸。** `gMGPipeCallbacks` 的五个条目仍是进程级函数指针(每个 session 装的是同一批函数),`Close()` 只有在 `ServerSessionCount()` 归零时才清;`g_sessionOwner` 的 CAS 抢占对**有 runtime 的 session 不再生效**(共表是合法的),只对「进程就是一个 session」的形状(inproc client+server 角色、`ServerLoopTest` 的 `FvSession` 及其对等对象)保留原样的 `Fatal{RoleViolation,"callback-double-install"}`。 +**The global callback table: installed once, routed by thread, removed only when the last session closes.** The five entries of `gMGPipeCallbacks` remain process-level function pointers (every session installs the same set); `Close()` clears them only when `ServerSessionCount()` reaches zero; `g_sessionOwner`'s CAS claim **no longer applies to sessions with a runtime** (a shared table is legal), and keeps the original `Fatal{RoleViolation,"callback-double-install"}` only for shapes where "the process is one session" (the inproc client+server roles, `ServerLoopTest`'s `FvSession` and its peers). -**surface mode 仍是 D4 的 per-session 闩**(`ServerLoop::m_surfaceMode`)。本切片一度引入 `SetDeclaredSurfaceMode`,让 `RunSession` 按**进程自己的** `MOBILEGL_IPC_SURFACE` 给 session 声明模式——**已撤掉**,两条理由:(a) 进程级的环境变量说不了统一 server 同时持有的多个 session(§4 第 5 条要的是口径不变、闩不许提升到进程级),(b) 它对 dial 进来的 client 是错的——pre-started server 不继承 client 的 env(`ServerOwnedSurfaceTest` 的 TCP 形状),于是 session 被声明成 offscreen,ServerOwned 的建面先拿 `SurfaceModeMismatch`,永远走不到「本 server 没有 display」那条具名拒绝。**而且它不需要**:`m_surfaceMode` 是 `ServerLoop` 的成员,每个 session 有自己的 loop,两个 session 各自闩各自的模式——「每 session 独立 surface mode」正是这个形状,不需要任何声明。真正想在第一个 surface 之前声明模式的形状(P14d 的 KWin on-screen + Konsole offscreen 同一个 server)必须**让模式上 wire**(Hello 或一条 SurfaceOp),那是 P14d 的账;在那之前,谁先建 surface 谁闩定,是每个 session 各自的答案。**`ServerDisplay` 的 lease 天然多路复用**:holder 是 loop 指针,`AcquireFor` 只会把窗口租给一个 session,第二个 on-screen session 拿到的是**具名拒绝** `NoServerWindow`(日志里点名 LeasedElsewhere),不再是注释里那句「sessions are sequential: a bug if seen」;offscreen session 完全不取 lease,可以任意多。 +**The surface mode is still D4's per-session latch** (`ServerLoop::m_surfaceMode`). This slice once introduced `SetDeclaredSurfaceMode`, letting `RunSession` declare a mode for the session from the **process's own** `MOBILEGL_IPC_SURFACE`—**it has been withdrawn**, for two reasons: (a) a process-level environment variable cannot speak for the multiple sessions a unified server holds at once (§4 item 5 asks for unchanged wording and a latch that must not be raised to process level), and (b) it is wrong for a client that dials in—a pre-started server does not inherit the client's env (the TCP shape of `ServerOwnedSurfaceTest`), so the session is declared offscreen, ServerOwned's surface creation hits `SurfaceModeMismatch` first, and it never reaches the named refusal "this server has no display". **And it is not needed**: `m_surfaceMode` is a member of `ServerLoop`, each session has its own loop, and the two sessions latch their own modes—"an independent surface mode per session" is exactly this shape and needs no declaration at all. A shape that really wants to declare the mode before the first surface (P14d's KWin on-screen + Konsole offscreen on the same server) must **put the mode on the wire** (in Hello or a SurfaceOp); that is P14d's debt; until then, whoever creates the first surface latches it, and that is each session's own answer. **`ServerDisplay`'s lease is naturally multiplexed**: the holder is a loop pointer, `AcquireFor` leases the window to only one session, and a second on-screen session gets the **named refusal** `NoServerWindow` (naming LeasedElsewhere in the log), no longer the comment's "sessions are sequential: a bug if seen"; offscreen sessions take no lease at all and can be arbitrarily many. -**接入层**:`UnixInProcessSupervisor`(`mobilegl_server_serve_inprocess` 的 unix 分支)从「一次一个 + 第二个 Refuse{Busy} one session is already active」改成**并发至多 `MOBILEGL_IPC_INPROC_MAX_SESSIONS`(默认 16)**,每个 session 一条控制线程,超限时用 fork 路径同一句话 `Refuse{Busy} the session limit is reached`;embedded ABI 的签名不变。**没动的三处**:`--serve --max-sessions` 的 fork worker 路径(进程隔离仍是可选形态,`UnixSupervisor.ConcurrentSharedMemoryClientsHaveSeparateWorkersAndAnExitedSlotIsReused` 与 `...RequiresAnExplicitLimit` 照旧)、TCP 的 in-process 形状(仍是一 session 一次,`InProcessServer.AnAuthenticatedSecondHelloWhileASessionIsLiveIsRefusedBusy` 照旧)、`TcpSupervisor` 的 fork 形状。与本文 §4 第 1 条写的「默认 8」差一个数:本切片取 16,且上限是环境变量而非新 ABI 参数。 +**The access layer**: `UnixInProcessSupervisor` (the unix branch of `mobilegl_server_serve_inprocess`) goes from "one at a time + a second gets Refuse{Busy} one session is already active" to **concurrent up to `MOBILEGL_IPC_INPROC_MAX_SESSIONS` (default 16)**, one control thread per session, and over the limit it uses the same sentence as the fork path, `Refuse{Busy} the session limit is reached`; the embedded ABI signature is unchanged. **Three places untouched**: the `--serve --max-sessions` fork worker path (process isolation remains an optional shape; `UnixSupervisor.ConcurrentSharedMemoryClientsHaveSeparateWorkersAndAnExitedSlotIsReused` and `...RequiresAnExplicitLimit` stay as they are), the in-process TCP shape (still one session at a time; `InProcessServer.AnAuthenticatedSecondHelloWhileASessionIsLiveIsRefusedBusy` stays), and the fork shape of `TcpSupervisor`. One number differs from "default 8" written in §4 item 1 of this document: this slice takes 16, and the limit is an environment variable rather than a new ABI parameter. -**验收证据**(本切片新增):`MG_Test/Wire/MultiSessionTest.cpp` 三个用例——`MultiSessionFixture.TwoShmSessionsInOneProcessAreServedAtOnce`(同进程两个 SHM session 并发:两个 Welcome 同 pid、日志里两条 `in-process unix session #N started`、各自 clear 各自读回自己的颜色)、`MultiSessionFixture.SameNamesInTwoSessionsDoNotCollide`(同一 client context token 与同一 render state handle 在两个 session 里都被接受——名字是 session 内的名字)、`MultiSessionFixture.ClosingOneSessionLeavesTheOtherServing`(A 关掉并 reap 之后 B 继续 apply 三条记录,进程级 resolver/回调表没被 A 卸掉)。既有套件不回归:本切片点名的 `InProcessServerTest`、`ServerDisplayTest`、`UnixSupervisor`、`SupervisorChildren`、`ServerLoopTest`/`ServerLoopEglTest`/`ServerLoopLatchTest`、`EmbeddedServerTest`、`PeerLatchTest`(含 `PeerLatch.SiteMap`,其 FatalFunnel 的 check 正则已跟着 domain 改写更新)、`ServerOwnedSurfaceTest`、`SessionHandshakeTest`、`SurfaceControlFrameTest` 全绿(host ctest 里剩下的失败只有 `3rdparty/glslang` 那个 dirty submodule 造成的编译/链接期基线失败,与本切片无关)。 +**Acceptance evidence** (added by this slice): three cases in `MG_Test/Wire/MultiSessionTest.cpp`—`MultiSessionFixture.TwoShmSessionsInOneProcessAreServedAtOnce` (two SHM sessions concurrently in one process: two Welcomes with the same pid, two `in-process unix session #N started` lines in the log, each clears and reads back its own color), `MultiSessionFixture.SameNamesInTwoSessionsDoNotCollide` (the same client context token and the same render state handle are both accepted in two sessions—names are names within a session), `MultiSessionFixture.ClosingOneSessionLeavesTheOtherServing` (after A is closed and reaped, B keeps applying three records; the process-level resolver/callback table was not removed by A). The existing suites do not regress: `InProcessServerTest`, `ServerDisplayTest`, `UnixSupervisor`, `SupervisorChildren`, `ServerLoopTest`/`ServerLoopEglTest`/`ServerLoopLatchTest`, `EmbeddedServerTest`, `PeerLatchTest` (including `PeerLatch.SiteMap`, whose FatalFunnel check regex was updated with the domain rewrite), `ServerOwnedSurfaceTest`, `SessionHandshakeTest`, `SurfaceControlFrameTest` are all green (the only remaining failures in host ctest are the compile/link-time baseline failures caused by the dirty `3rdparty/glslang` submodule, unrelated to this slice). -**修正(`HealthySessionWithColor` 的颜色解包)**:本切片把 `P12ServerRig.h` 的绿色 clear 参数化时,一度把 `rgba` 按 `A<<24|B<<16|G<<8|R` 的逆序解包(把最高字节当 R),于是 `0xFF00FF00`(绿)被清成 `0x00FF00FF`(品红),`InProcessServer.SequentialSessions...` 的读回断言因此挂掉。正确的解包就是读回自己的字节序——`PeerReport::pixel` 是 GL_RGBA/GL_UNSIGNED_BYTE 三元组的 little-endian `Uint32`,故 `R = rgba & 0xFF … A = rgba >> 24`。**生产路径(clear → read_pixels)一个字节没动**:`PeerLatchTest` 用同一绿色的字面量 `{0,1,0,1}` 且断言同一个 `0xFF00FF00`,它的对应用例全程是绿的,就是这条结论的控制。红色 `0xFF0000FF` 在字节反转下是回文,所以当时只有绿色 session 失败——这不是两个 bug。 +**Correction (the color unpacking of `HealthySessionWithColor`)**: when this slice parameterized the green clear in `P12ServerRig.h`, it once unpacked `rgba` in the reversed order `A<<24|B<<16|G<<8|R` (treating the top byte as R), so `0xFF00FF00` (green) was cleared to `0x00FF00FF` (magenta), and `InProcessServer.SequentialSessions...`'s readback assertion failed. The correct unpacking is simply readback's own byte order—`PeerReport::pixel` is a little-endian `Uint32` of a GL_RGBA/GL_UNSIGNED_BYTE triple, so `R = rgba & 0xFF … A = rgba >> 24`. **The production path (clear → read_pixels) did not change a byte**: `PeerLatchTest` uses the same green literal `{0,1,0,1}` and asserts the same `0xFF00FF00`, and its corresponding case was green throughout, which is the control for this conclusion. Red `0xFF0000FF` is a palindrome under byte reversal, which is why only the green session failed at the time—this is not two separate bugs. -**本切片明确没做(下一层的账)**:DirectGLES 的 `g_Display/g_Config/g_Context/g_Surface` 与六个 twin registry 仍是进程级(P14b 的 per-context native tuple),所以两个并发 session 的**原生上下文并不隔离**:一个 session 的 teardown 仍会拆掉进程的 EGL context,本切片的渲染验收因此只在两个 session 都活着时做,关掉一个之后的证据是记录级的(记录照常 apply 并有回包)。`MGPipeServerSetContextLive` / `MGPipeServerSetOwnedWindow` 与 `PipeInputs.cpp` 同属进程级,不在本切片的文件范围内。`MG_Util::PipeStats::Init/Shutdown` 仍是进程级,多 session 下是遥测噪声不是正确性。`SessionFail`(未武装时的真 Fatal)仍会带走整个进程——那是 `--serve` fork 形状存在的理由。 +**What this slice explicitly did not do (the next layer's debt)**: DirectGLES's `g_Display/g_Config/g_Context/g_Surface` and the six twin registries are still process-level (P14b's per-context native tuple), so the **native contexts of two concurrent sessions are not isolated**: one session's teardown still tears down the process's EGL context, so this slice's rendering acceptance is done only while both sessions are alive; the evidence after closing one is at the record level (records are still applied and get replies). `MGPipeServerSetContextLive` / `MGPipeServerSetOwnedWindow` and `PipeInputs.cpp` are likewise process-level and outside this slice's file set. `MG_Util::PipeStats::Init/Shutdown` is still process-level; under multiple sessions it is telemetry noise, not correctness. `SessionFail` (a real Fatal when not armed) still takes the whole process down—that is the reason the `--serve` fork shape exists. -## 后端(DirectGLES) +## Backend (DirectGLES) -1. **native tuple per context**。`g_Display` 保留进程级(native display 一次 initialize 合理);`g_Context`/`g_Surface`/`g_Config`(`DirectGLES.cpp:16183-16186`)改为 per-(session, contextSlot) 表,native context 按 share group 用 `eglCreateContext(share=…)` 建。 -2. **拆掉无条件 teardown**。`InitDisplayAndContext` 首句 `DestroyEGLContext()`(`DirectGLES.cpp:16569`)与 `BackendObject_DirectGLES` 建 surface 前的 `DestroyEGLContext()+ResetEGLRuntimeState()`(`BackendObject_DirectGLES.cpp:972-982`、`:1007-1014`)改为:目标 context 已存在则复用其 native context,仅换绑 surface;pbuffer→window→pbuffer 不丢资源。`DestroyEGLContext` 只拆指定 context;最后一个 context 走了才 `eglTerminate`。 -3. **Managers 按 share group / context 分表**。六个 twin registry(`Managers.cpp:6895`、`:11035`、`:12835`、`:13188`、`:16255`、`:16580`)按 share group 实例化;`g_activeTextureUnit`/`g_boundTexturesCache`/sampler cache(`Managers.cpp:11031-11032` 等)按 context 实例化;`DropEveryTwinForEndedServerSession`(`Managers.cpp:425-443`)只清本 session。`g_backendContextGeneration` 改为 per-context 世代。**(twin 键与 per-session 清理已落地,见 S6;单元影子与 context 世代仍欠。)** -4. **DirectVulkan 同步审视**。Magma 的 per-device/per-queue 结构也要按 session 分;本阶段先保证不编译退化,多 session 下 Magma 的验收单列。 +1. **Native tuple per context**. `g_Display` stays process-level (initializing the native display once is reasonable); `g_Context`/`g_Surface`/`g_Config` (`DirectGLES.cpp:16183-16186`) become a per-(session, contextSlot) table; native contexts are created per share group with `eglCreateContext(share=…)`. +2. **Remove the unconditional teardown**. `InitDisplayAndContext`'s first statement `DestroyEGLContext()` (`DirectGLES.cpp:16569`) and `BackendObject_DirectGLES`'s `DestroyEGLContext()+ResetEGLRuntimeState()` before surface creation (`BackendObject_DirectGLES.cpp:972-982`, `:1007-1014`) become: if the target context already exists, reuse its native context and only rebind the surface; pbuffer→window→pbuffer loses no resources. `DestroyEGLContext` tears down only the given context; `eglTerminate` only when the last context is gone. +3. **Managers: one table per share group / context**. The six twin registries (`Managers.cpp:6895`, `:11035`, `:12835`, `:13188`, `:16255`, `:16580`) are instantiated per share group; `g_activeTextureUnit`/`g_boundTexturesCache`/the sampler cache (`Managers.cpp:11031-11032` etc.) per context; `DropEveryTwinForEndedServerSession` (`Managers.cpp:425-443`) clears only this session. `g_backendContextGeneration` becomes a per-context generation. **(The twin key and per-session cleanup have landed, see S6; the unit shadow and the context generation are still owed.)** +4. **Review DirectVulkan alongside**. Magma's per-device/per-queue structures also need to be split by session; this phase only ensures no compile regression, and Magma's acceptance under multiple sessions is listed separately. -### S4 已落地形状(每 context 原生 tuple + share-group 键控) +### S4 landed shape (native tuple per context + share-group keying) -上面第 1、2 条是 P14b 的目标形状;S4 落地了「native tuple 按 context 归属、创建第二个 context/surface 不再拆 context、share group 进原生」这一层,实际形状如下。 +Items 1 and 2 above are P14b's target shape; S4 landed the layer "native tuple attributed by context, creating a second context/surface no longer tears down the context, share group enters native", and the actual shape is below. -**native tuple 按 (session, token) 键控**(`MG_Backend/DirectGLES/DirectGLES.cpp` 的 `NativeContextTuple` / `NativeSessionState` 注册表)。`g_Display` 仍是进程级一份、`eglInitialize` 一次,只有最后一个原生 context 走了才 `eglTerminate`(`g_displayUsers` 计数)。`EGLContext`/`EGLConfig` 随 tuple;**原生 surface 按 session 一份**(EGL 里 surface 不属于 context,只有 draw/read 绑定属于),tuple 记自己当前画到哪个 surface。键由 server 层装的探针回答(`SetNativeContextKeyResolver`,`MG_Remote/Server/SessionRuntime.cpp` 经 `ThreadSessionScope` 装一次):答案是**本线程的 session 身份 + `ServerSession::CurrentContextToken()`**;没有探针的线程(monolith、纯前端进程、unit case、inproc 单进程形状)答案恒为 `{0,0}`——这正是被替换掉的进程单例,所以单 context 世界逐字不变。 +**The native tuple is keyed by (session, token)** (`MG_Backend/DirectGLES/DirectGLES.cpp`'s `NativeContextTuple` / `NativeSessionState` registry). `g_Display` is still one per process with a single `eglInitialize`, and `eglTerminate` only when the last native context is gone (`g_displayUsers` counter). `EGLContext`/`EGLConfig` follow the tuple; **the native surface is one per session** (in EGL a surface does not belong to a context, only the draw/read binding does), and the tuple records which surface it currently draws to. The key is answered by a probe the server layer installs (`SetNativeContextKeyResolver`, installed once in `MG_Remote/Server/SessionRuntime.cpp` through `ThreadSessionScope`): the answer is **this thread's session identity + `ServerSession::CurrentContextToken()`**; on a thread without a probe (monolith, pure frontend process, unit case, inproc single-process shape) the answer is always `{0,0}`—which is exactly the process singleton being replaced, so the single-context world is unchanged character for character. -**创建不再拆 context**。`InitDisplayAndContext()`(首句无条件 `DestroyEGLContext()`)换成 `EnsureNativeContext(tuple, surfaceBit, window)`:tuple 已有原生 context 就复用,只按需要选 config;没有才建。`BackendObject_DirectGLES::CreateEGL{Window,Pbuffer}Surface` 里的 `DestroyEGLContext()+ResetEGLRuntimeState()` 同样去掉 teardown,只留 base class 的 per-surface bookkeeping。因此 pbuffer→window→pbuffer 只是往 session 的 surface 集合里加/换,tuple 的 `EGLContext` 一字不动——对象(后端 twin 直接活在原生 context 里)自然不丢。`DestroyEGLContext()` 现在是**本 session** 的全量 teardown(`ReleaseEGLResources`/`~BackendObject_DirectGLES` 的语义),单个 context 的销毁是新的 `DestroyNativeContextFor(token)`。 +**Creation no longer tears down the context**. `InitDisplayAndContext()` (whose first statement was the unconditional `DestroyEGLContext()`) is replaced by `EnsureNativeContext(tuple, surfaceBit, window)`: if the tuple already has a native context, reuse it and only choose a config if needed; create one only if there is none. `BackendObject_DirectGLES::CreateEGL{Window,Pbuffer}Surface` likewise drops the teardown of `DestroyEGLContext()+ResetEGLRuntimeState()` and keeps only the base class's per-surface bookkeeping. So pbuffer→window→pbuffer merely adds to or switches within the session's surface set, and the tuple's `EGLContext` does not change a character—so objects (backend twins live directly in the native context) are naturally not lost. `DestroyEGLContext()` is now the **session's** full teardown (the semantics of `ReleaseEGLResources`/`~BackendObject_DirectGLES`); destroying a single context is the new `DestroyNativeContextFor(token)`. -**share group 进原生**(`CreateNativeContextFor(token, shareGroup)`)。`CreateContext` 控制帧到达时,server 为该 token 建原生 context:**同 session 内、同一 shareGroupToken 且已有活 context 的 tuple 的 `EGLContext` 作为 `eglCreateContext` 的 share 参数**,否则 `EGL_NO_CONTEXT`。组内后续 context 因此共享原生对象命名空间。建失败则回滚该 session 表项并把 `ok=false` 回给客户端。 +**The share group enters native** (`CreateNativeContextFor(token, shareGroup)`). When the `CreateContext` control frame arrives, the server creates a native context for the token: **within the same session, the `EGLContext` of the tuple with the same shareGroupToken that already has a live context is used as the share parameter of `eglCreateContext`**, otherwise `EGL_NO_CONTEXT`. Later contexts in the group therefore share the native object namespace. If creation fails, it rolls back that session entry and returns `ok=false` to the client. -**bind_context 是原生切换点**。MakeCurrent 控制帧到的时刻 `CurrentContextToken()` 还是旧值(S1 刻意让客户端在 make-current 成功后才发绑定记录),所以在那里切原生会绑到刚离开的 context。`ServerVerbSink::OnBindContext`(`MG_Remote/Server/PipeApplier.cpp`)在 `session->BindContext(token)` 之后调 `DirectGLES::MakeNativeContextCurrentForBoundToken()`:按新 token 解析 tuple,与 `t_boundNativeContext` 相同就返回(单 context 的每次绑定零成本),不同才做原生 `eglMakeCurrent`。 +**`bind_context` is the native switch point**. When the MakeCurrent control frame arrives, `CurrentContextToken()` is still the old value (S1 deliberately lets the client emit the binding record only after make-current succeeds), so switching native there would bind to the context just left. `ServerVerbSink::OnBindContext` (`MG_Remote/Server/PipeApplier.cpp`) calls `DirectGLES::MakeNativeContextCurrentForBoundToken()` after `session->BindContext(token)`: resolve the tuple by the new token, return if it is the same as `t_boundNativeContext` (each bind of a single context costs zero), and do a native `eglMakeCurrent` only when different. -**验收证据**(本次新增,`MG_Test/Wire/ServerLoopTest.cpp`,真实 headless EGL):`ServerLoopEglTest.CreatingASecondContextLeavesTheFirstNativeContextAlive`(同一 session 三个 context token,三个原生 EGLContext 同时活着且互不相同——还原 S4 前的无条件 teardown 时只剩一个);`ServerLoopEglTest.CreatingAnotherSurfaceKeepsTheSameNativeContext`(建第二个 pbuffer 后 tuple 的 `EGLContext` 句柄不变、原生 context 数仍为 1)。既有集合零回归:本切片点名的 97 个用例全绿(86 基线 + 11 `ServerLoopEglTest` + 上面两个)。 +**Acceptance evidence** (added this commit, `MG_Test/Wire/ServerLoopTest.cpp`, real headless EGL): `ServerLoopEglTest.CreatingASecondContextLeavesTheFirstNativeContextAlive` (three context tokens in one session; three native EGLContexts alive at the same time and distinct—restoring the pre-S4 unconditional teardown leaves only one); `ServerLoopEglTest.CreatingAnotherSurfaceKeepsTheSameNativeContext` (after creating a second pbuffer the tuple's `EGLContext` handle is unchanged and the native context count is still 1). The existing set does not regress: the 97 cases this slice names are all green (86 baseline + 11 `ServerLoopEglTest` + the two above). -**本切片明确没做(下一层的账)**: +**What this slice explicitly did not do (the next layer's debt)**: -- **`g_applier` 没有改成 {shareGroup → applier}**(上面 server 第 3 条)。原因不是时间,是**形状**:`MGPipeApplierState` 把「share group 的对象记录」和「每 context 的 working state」混在一个结构里(`PipeApply.h:515-933`,其自身注释第 101 行已指出该二分),照字面把它按 share group 键控会让**同一 share group 的两个 context 共用 working state**——bindings、current program、unit 集互相覆盖,比不改更错。正确的做法是先按该二分拆结构(对象表进 share group、working state 进 context),那是独立的一刀。今天 `g_applier` 与 `gMGPipeApplierReset` 逐字未动。**(S5 已做,见下节。)** -- **六个 twin registry 与 twin 键 `{shareGroup, slot, gen}` 未改**(`Managers.cpp`)。twin 仍按引用活着的后端 context 复用,多 context 下的正确性依赖「一个原生 context 一个 twin 世代」,这在两个 context 都活着时成立(本次测到的),在跨 context 迁移 twin 的路径上还没有证据。**(S5 仍未做;S6 已做,见「S6 已落地形状」。)** -- **share group 的驱动级证明未落地**。`eglCreateContext(share=…)` 已接线,但用 headless EGL 直接问 `glIsBuffer` 的探针在本机没有得到可用的控制(同 context 内 `glGenBuffers` 后 `glIsBuffer` 即返回 false),没有作为「跑了个空的绿」收进来。要证到驱动层,需要先弄清该探针,再补一个用例。**(S5 也没弄清:见 S5 的未做项与「为什么没做」。)** -- **Wire 第 1 条的逐记录 `ContextSlot` 未做**,仍是 S1 的边沿宣告 + `bind_context`。 -- **`g_backendContextGeneration`/`g_syncContextGeneration` 仍是进程级**:销毁单个 context 会推进全局世代,其他 context 的旧 fence/query 句柄因此读作「已 signal」。安全方向(最坏是多等),但不是每 context 世代,属 P14b/c。 -- **ServerLoop 的 MakeCurrent 去重仍是「当前绑定的那一个 tuple」**,不是 per-context 表。理由写在 `ServerLoop.h:560-573`:ID-67 的钉死用例(A→B→A 必须三次原生绑定)定义「不同 tuple」为**当前绑定**的变化,而 EGL 里一个线程同时只有一个 current context,回到 A 确实必须重跑那七条前端 context 失效。「每 context 持有自己的 native triple」由后端的 {session, token} 注册表满足,去重这一层的单位仍是线程的当前绑定。 +- **`g_applier` was not changed to {shareGroup → applier}** (server item 3 above). The reason is not time but **shape**: `MGPipeApplierState` mixes "the share group's object records" and "the per-context working state" in one structure (`PipeApply.h:515-933`; its own comment at line 101 already points out this split), and keying it by share group literally would make **two contexts of the same share group share working state**—bindings, current program and unit sets overwrite each other, which is worse than not changing. The right approach is to first split the structure along that line (object tables into the share group, working state into the context), which is a separate cut. Today `g_applier` and `gMGPipeApplierReset` are untouched character for character. **(S5 did it, see the next section.)** +- **The six twin registries and the twin key `{shareGroup, slot, gen}` are unchanged** (`Managers.cpp`). A twin is still reused by a backend context that is alive by reference; correctness under multiple contexts rests on "one native context, one twin generation", which holds while both contexts are alive (measured this time) but has no evidence on paths that migrate a twin across contexts. **(S5 still did not do it; S6 did, see "S6 landed shape".)** +- **Driver-level proof of the share group did not land**. `eglCreateContext(share=…)` is wired, but the probe that asks `glIsBuffer` directly through headless EGL got no usable control on this machine (`glIsBuffer` returns false right after `glGenBuffers` in the same context), so it was not taken in as "an empty run that was green". Proving it at the driver layer requires understanding that probe first and then adding a case. **(S5 did not figure it out either: see S5's not-done items and "why it was not done".)** +- **Wire item 1's per-record `ContextSlot` is not done**; it is still S1's edge announcement + `bind_context`. +- **`g_backendContextGeneration`/`g_syncContextGeneration` are still process-level**: destroying a single context advances the global generation, so other contexts' old fence/query handles read as "already signaled". The safe direction (at worst waiting longer), but not a per-context generation; belongs to P14b/c. +- **ServerLoop's MakeCurrent deduplication is still "the one currently bound tuple"**, not a per-context table. The reason is in `ServerLoop.h:560-573`: ID-67's pinned case (A→B→A must be three native binds) defines "different tuple" as a change of **the current binding**, and in EGL a thread has only one current context at a time, so returning to A really must rerun those seven frontend context invalidations. "Each context holds its own native triple" is satisfied by the backend's {session, token} registry; the unit of this deduplication layer is still the thread's current binding. -### S5 已落地形状(applier 按 {session, context} / {session, shareGroup} 键控) +### S5 landed shape (applier keyed by {session, context} / {session, shareGroup}) -S4 留下的最后一块:`PipeApply.cpp` 的进程级 `g_applier` 现在是一个**每 (session, context) 的注册表**,它的对象记录按 {session, share group} 分桶。 +The last piece S4 left: `PipeApply.cpp`'s process-level `g_applier` is now a **per-(session, context) registry**, whose object records are bucketed by {session, share group}. -**结构拆分(`MG_Pipe/PipeApply.h`)**。原来一个 `MGPipeApplierState` 按两个寿命切成两个结构: +**Structure split** (`MG_Pipe/PipeApply.h`). The former single `MGPipeApplierState` is split into two structures by two lifetimes: -| `MGPipeObjectRecords`(share group) | `MGPipeWorkingState`(context) | +| `MGPipeObjectRecords` (share group) | `MGPipeWorkingState` (context) | |---|---| -| `Resources`、`VertexElementsCsos`、`TextureResources`、`RenderbufferResources`、`SamplerCsos`、`SamplerViewCsos`、`ShaderCsos`、`CompositeShaderCsos`、`FramebufferRecords` | `RenderStateCsos`、`BoundRenderStateCso`、`Residual`、`ScatteredChunkBits`、四个 wire 计数器与四个 refusal 计数器、`BoundVertexElements`/`VertexBuffers*`/`IndexBuffer*`、`MapPersistentRoundtrips`、`BoundFramebuffer`/`FramebufferSerial`/`StaleFramebufferRecordLookups`、三个 unit 窗口、三个 program handle、三个 binding-point 窗口、`IsTransformFeedbackActive`、`TextureShutterSerial`/`ContextSerial`、`#if DISAGGREGATED` 的 verb handle 组 | +| `Resources`, `VertexElementsCsos`, `TextureResources`, `RenderbufferResources`, `SamplerCsos`, `SamplerViewCsos`, `ShaderCsos`, `CompositeShaderCsos`, `FramebufferRecords` | `RenderStateCsos`, `BoundRenderStateCso`, `Residual`, `ScatteredChunkBits`, the four wire counters and the four refusal counters, `BoundVertexElements`/`VertexBuffers*`/`IndexBuffer*`, `MapPersistentRoundtrips`, `BoundFramebuffer`/`FramebufferSerial`/`StaleFramebufferRecordLookups`, the three unit windows, the three program handles, the three binding-point windows, `IsTransformFeedbackActive`, `TextureShutterSerial`/`ContextSerial`, the verb handle group under `#if DISAGGREGATED` | -`RenderStateCsos` 在 working 一侧不是笔误:它今天是**被 `MGPipeApplierReset` 清掉的**(每个 make-current 一份新 CSO 表),照旧规则留在 per-context 那半。`FramebufferRecords` 留在对象一侧也是照旧规则(reset 不清它),且它的槽来自全局分配器,所以一个 share group 装两个 context 的记录是「更宽的表」而不是别名。 +`RenderStateCsos` on the working side is not a typo: it is **cleared by `MGPipeApplierReset`** today (a fresh CSO table per make-current), and by the existing rule it stays in the per-context half. `FramebufferRecords` staying on the object side is also by the existing rule (reset does not clear it), and its slots come from the global allocator, so one share group holding the records of two contexts is "a wider table" rather than an alias. -`MGPipeApplierState` 现在**继承** `MGPipeWorkingState` 并持有一个 `MGPipeObjectRecords& Objects`,另把九张对象表**按原名字绑成引用成员**(`Resources`、`TextureResources`…)。理由写在头里:MG_Backend / MG_IntegrationTest / MG_Test 里 ~200 个调用点一直把 `st.Resources` 读作「这个对象的 share group 记录」,绑引用让这些读点**一个不改**且按各自 context 所属的 group 正确解析;把键控改动变成改名改动只增风险不增正确性。头文件里可以同时用 `Objects.X`(在**创建**两半的地方显式点出群体)与 `X`(后端一直的拼法),两者是同一张表。 +`MGPipeApplierState` now **inherits** `MGPipeWorkingState` and holds a `MGPipeObjectRecords& Objects`, and also binds the nine object tables **as reference members under their original names** (`Resources`, `TextureResources`…). The reason is written in the header: the ~200 call sites in MG_Backend / MG_IntegrationTest / MG_Test have always read `st.Resources` as "this object's share group record"; binding references leaves those read sites **unchanged** while resolving correctly by the group their context belongs to; turning a keying change into a renaming change adds risk without adding correctness. The header can use both `Objects.X` (making the group explicit where the two halves are **created**) and `X` (the spelling the backend has always used); they are the same table. -**注册表与解析链(`PipeApply.cpp`)**。三层,和 S2 的 `gPipeInputs`、S4 的 native tuple key 同构: +**Registry and resolution chain** (`PipeApply.cpp`). Three layers, isomorphic to S2's `gPipeInputs` and S4's native tuple key: -- `MGPipeApplierKey{ SessionKey, ContextToken }`,由 `MGPipeSetApplierKeyResolver` 装的探针回答;`SessionRuntime.cpp` 在 `InstallSessionRuntimeHooks` 里装(`ThreadSessionScope` 一开就装)。探针答案是**本线程 session 的 `ServerSession*` 地址 + `CurrentContextToken()`**;不是 session 线程的答案 false,拿到进程级 applier —— 这正是被替换掉的单例,所以 monolith / 纯客户端 / inproc 单进程形状 / 单元用例逐字不变。 -- `MGPipeApplierRegisterContext(session, token, groupToken)` / `MGPipeApplierUnregisterContext` / `MGPipeApplierReleaseSession`。**注册而不是推断**:`ServerSession::CreateContext` / `DestroyContext` 在 apply 线程上调用它们,所以解析探针永远是「读本 session 已经在维护的当前 token」两字,不必从别的线程去读 session 的 map;`Accept` 与 `~SessionRuntime` 释放整 session。 -- **group 键**:`shareGroupToken != 0 ? shareGroupToken : (contextToken | 高位哨兵)`。前端铸的 share group token 与 context token 来自两个计数器,不隔离就会让 group 7 和 context 7 变成一组;`0` 是 S1 注释里「本 context 自己起了一个组」的哨兵(也是 `ServerCreateEGLContext(token, 0, 0)` 这类手工建 context 传的值),落成「自己的组」而不是「和别的 0 一组」。 -- **最后一个 context 走才释放该组的对象记录**(`MGPipeApplierReleaseObjectRecords` 的 per-group 版);一组的另一个 context 还在时记录一条不丢。 -- **线程局部缓存 + 世代号**。`MGPipeApplier()` 是后端按状态读调的,所以快路径是「本线程上次的 (session, token) 与注册表世代都对得上就直接返回」;注册表每次变动 `++generation`,缓存指针只有在世代相等时才被解引用 —— 这就是「另一个线程销毁了 context」不会留下悬垂缓存的原因。快路径开销是三个 TLS 读、一次原子读、两次比较;探针为 null(monolith)时是一次函数指针比较。 +- `MGPipeApplierKey{ SessionKey, ContextToken }`, answered by a probe installed by `MGPipeSetApplierKeyResolver`; `SessionRuntime.cpp` installs it in `InstallSessionRuntimeHooks` (installed as soon as `ThreadSessionScope` opens). The probe's answer is **the address of this thread's session's `ServerSession*` + `CurrentContextToken()`**; a thread that is not a session thread answers false and gets the process-level applier—which is exactly the singleton being replaced, so monolith / pure client / inproc single-process shape / unit cases are unchanged character for character. +- `MGPipeApplierRegisterContext(session, token, groupToken)` / `MGPipeApplierUnregisterContext` / `MGPipeApplierReleaseSession`. **Register rather than infer**: `ServerSession::CreateContext` / `DestroyContext` call these on the apply thread, so the resolution probe is always just "read the current token this session already maintains", without reading the session's map from another thread; `Accept` and `~SessionRuntime` release the whole session. +- **Group key**: `shareGroupToken != 0 ? shareGroupToken : (contextToken | high-bit sentinel)`. The frontend's share group tokens and context tokens come from two counters; without isolation, group 7 and context 7 would become one group; `0` is the sentinel for "this context started its own group" from the S1 comment (and the value passed by hand-built contexts such as `ServerCreateEGLContext(token, 0, 0)`), landing as "its own group" rather than "the same group as the other 0". +- **The group's object records are released only when the last context leaves** (the per-group version of `MGPipeApplierReleaseObjectRecords`); while the other context of a group is still there, not one record is lost. +- **Thread-local cache + generation number**. `MGPipeApplier()` is called by the backend on every state read, so the fast path is "if this thread's last (session, token) and the registry generation both match, return directly"; every registry change does `++generation`, and a cached pointer is dereferenced only when the generations are equal—that is why "another thread destroyed the context" leaves no dangling cache. The fast path costs three TLS reads, one atomic read and two comparisons; with a null probe (monolith) it is one function pointer comparison. -**前端/会话接入**:`EGLImpl::MakeCurrent` 的 `EmitContextBinding` 一字未动 —— S1 的边沿宣告本来就是「这条 ring 往后归谁」的全部信息,S5 只是第一次**读**它。 +**Frontend/session integration**: `EGLImpl::MakeCurrent`'s `EmitContextBinding` is untouched—S1's edge announcement was always all the information "this ring belongs to whom from now on", and S5 is simply the first time **reading** it. -**验收证据**(本次新增): +**Acceptance evidence** (added this commit): -- `MG_Test/Wire/ApplierOwnershipTest.cpp`,5 个用例,直接驱动注册表与解析(无 EGL、无 wire):两个 nonshared context 同名 handle 是两条记录且互不覆盖(reset 也不丢);同一 share group 的两个 context **共用对象表而各持 working state**(当前 program、vertex-buffer 窗口不互见,而一张表上的 create 两边可见);两个 session 用同名 group/context token 不共享任何东西;组的记录活到最后一个 context 才释放、重建的 token 不继承死组;无 session 的线程仍拿到进程级 applier。 - **负控**(必做,否则是空绿):把测试装的解析探针改成 null(即回到 S5 前的「谁都拿进程级 applier」),5 个用例**全红**;换回即全绿。 -- `MultiSessionTest.TwoSessionsInterleaveTwoContextsEachWithoutCrossTalk`:真实 `--serve` 前身(in-process unix supervisor)上两个 session,各自两个 context(同名 token 与同名 group token),**8 轮交错**:每轮先各发一条 `bind_context` 切 context,再跑一整趟 clear + 真读回。绿/红两种颜色互为证人;日志里 0 条 `SessionLatch{`。这条用例同时压的是**生产**解析链(`ThreadSessionScope` 装的探针)与并发(两个 apply 线程同时跑)。 -- 既有集合零回归:本切片点名的 97 个用例与 `MultiSessionFixture` 原有的 4 个全绿(含 `ServerLoopEglTest` 的 11 个、`ContextStateOwnershipTest` 6 个)。`SanityTest` 的两个用例因 `MGPipeApplierState` 不再可拷贝改为保存/恢复它真正改动的 working 字段。 -- **全量 host ctest 与基线的逐名对比**(不是"看起来差不多"):先 `git stash` 掉本切片的全部改动、重建、跑一遍全量(`ctest -j 8`,2735 个用例)留下失败名单,再恢复本切片、重建、跑同一遍,两份名单 `comm`: +- `MG_Test/Wire/ApplierOwnershipTest.cpp`, 5 cases, driving the registry and resolution directly (no EGL, no wire): same-named handles in two nonshared contexts are two records that do not overwrite each other (nor does reset lose them); two contexts of one share group **share the object table while each holds working state** (current program and vertex-buffer windows are not visible to each other, while a create on that one table is visible to both); two sessions with the same group/context token names share nothing; a group's records live until the last context leaves, and a re-minted token does not inherit a dead group; a thread without a session still gets the process-level applier. + **Negative control** (mandatory, otherwise it is an empty green): change the resolution probe the test installs to null (i.e. back to the pre-S5 "everyone gets the process-level applier"), and all 5 cases **go red**; switch it back and all are green. +- `MultiSessionTest.TwoSessionsInterleaveTwoContextsEachWithoutCrossTalk`: on the real `--serve` predecessor (the in-process unix supervisor), two sessions with two contexts each (same token names and same group token names), **8 interleaved rounds**: each round first sends one `bind_context` per session to switch context, then runs a full clear + real readback. The green and red colors witness for each other; 0 `SessionLatch{` lines in the log. This case stresses both the **production** resolution chain (the probe installed by `ThreadSessionScope`) and concurrency (two apply threads running at once). +- The existing set does not regress: the 97 cases this slice names and the original 4 cases of `MultiSessionFixture` are all green (including `ServerLoopEglTest`'s 11 and `ContextStateOwnershipTest`'s 6). Two `SanityTest` cases were changed to save/restore the working fields they really modify, because `MGPipeApplierState` is no longer copyable. +- **Name-by-name comparison of the full host ctest against the baseline** (not "looks about the same"): first `git stash` away all of this slice's changes, rebuild, run the full suite (`ctest -j 8`, 2735 cases) and keep the failure list; then restore this slice, rebuild, run the same pass, and `comm` the two lists: - | | 数量 | + | | Count | |---|---| - | 基线失败 | 266 | - | 本切片失败 | 265 | - | **本切片新增失败** | **0** | - | 基线失败而本切片不失败 | 1(`ProgramTest.CompileVertex`,glslang 那批的已知抖动) | + | Baseline failures | 266 | + | This slice's failures | 265 | + | **New failures in this slice** | **0** | + | Baseline failures that this slice does not fail | 1 (`ProgramTest.CompileVertex`, a known flake in the glslang batch) | - 失败名单全部落在 glslang / 着色器编译族(`ProgramTest`、`ProgramInterfaceTest`、`AsyncLinkTest`、`GlslangCaptureProbeTest`、`TranslationCacheTest`…),与 `3rdparty/glslang` 这个 dirty submodule 的既有基线一致。 + The failure lists all fall in the glslang / shader compilation family (`ProgramTest`, `ProgramInterfaceTest`, `AsyncLinkTest`, `GlslangCaptureProbeTest`, `TranslationCacheTest`…), consistent with the existing baseline of the dirty `3rdparty/glslang` submodule. -**S5 明确没做(下一层的账)**: +**What S5 explicitly did not do (the next layer's debt)**: -- **六个 twin registry 与 twin 键仍未改**(`MG_Backend/DirectGLES/Managers.cpp` 的六个 `g_backend*` 静态注册表;键在 `Managers.h:315` 的 `StateBackendObjectRegistry` → `SlotTables.h` 的 `BackendSlotTable`)。**这是 S5 之后"两个 nonshared context 的同名 handle"剩下的那一半**:applier 里两条记录是对的(有测试),但 twin 层按 `{slot, gen}` 键,两个 context 的同一个 handle 值会解析到同一个 twin;反向也一样,跨 context 复用 twin 的路径没有按 share group 分组。S4 报告里那条 `glIsBuffer` 探针本机仍无可用控制,所以**驱动级的 shared / nonshared 证据仍然是缺的**,本次没有以"跑了个空的绿"收进来(这是本切片最该被下一刀补上的证据)。改形状是把 `BackendSlotTable` 加一个 group 维度或按组实例化那六个注册表,触及 `Managers.cpp` 里全部调用点,不是本轮时间能稳妥做完的一刀。**(S6 已做,见下节;驱动级探针仍未弄清,S6 走的是 twin 身份这条替代证据。)** -- **pbuffer→pbuffer→pbuffer 的资源保留**只到 S4 已落地的程度(`ServerLoopEglTest.CreatingAnotherSurfaceKeepsTheSameNativeContext`:换 surface 不动 tuple 的 `EGLContext` 句柄)。真正的"三个 pbuffer 之间来回且资源都在"要 window 半边,本机 headless 验不了;按 S4 的口径只记录。 -- **wire 第 1 条的逐记录 `ContextSlot`** 仍未做,仍是 S1 的边沿宣告 + `bind_context`。所以"同一 ring 上两个 context 的记录交错"只在 client 按 make-current 顺序发射时成立(本轮的交错压力用例走的正是这个顺序)。 -- **`MGPipeApplierShareGroupCountForTesting`** 是测试观测面,不是生产 API。 -- **`MGPipeApplierState` 的九张表名与 `Objects.X` 两种拼法并存**是刻意换取 ~200 个读点不动的代价;改名的机会在 twin registry 一起做的那一刀。 -- **`g_backendContextGeneration`/`g_syncContextGeneration`、ServerLoop 的 MakeCurrent 去重**同 S4 一节所列,仍未动。 +- **The six twin registries and the twin key are still unchanged** (`MG_Backend/DirectGLES/Managers.cpp`'s six `g_backend*` static registries; the key is in `Managers.h:315`'s `StateBackendObjectRegistry` → `SlotTables.h`'s `BackendSlotTable`). **This is the remaining half of "same-named handles in two nonshared contexts" after S5**: the two records in the applier are right (tested), but the twin layer is keyed by `{slot, gen}`, so the same handle value from two contexts resolves to the same twin; the reverse also holds—paths that reuse a twin across contexts are not grouped by share group. The `glIsBuffer` probe from the S4 report still has no usable control on this machine, so **driver-level shared / nonshared evidence is still missing**, and it was not taken in this time as "an empty run that was green" (this is the evidence this slice most owes the next cut). Changing the shape means adding a group dimension to `BackendSlotTable` or instantiating the six registries per group, touching every call site in `Managers.cpp`; that is not a cut that can be completed safely in this round's time. **(S6 did it, see the next section; the driver-level probe is still unsolved, and S6 took the twin identity route as substitute evidence.)** +- **Resource retention across pbuffer→pbuffer→pbuffer** is only at the level S4 landed (`ServerLoopEglTest.CreatingAnotherSurfaceKeepsTheSameNativeContext`: switching surfaces does not change the tuple's `EGLContext` handle). The real "back and forth among three pbuffers with all resources intact" needs the window half and cannot be verified headless on this machine; recorded only, per S4's wording. +- **Wire item 1's per-record `ContextSlot`** is still not done, still S1's edge announcement + `bind_context`. So "records of two contexts interleaved on one ring" holds only when the client emits in make-current order (the interleaving stress case this round goes through exactly that order). +- **`MGPipeApplierShareGroupCountForTesting`** is a test observation surface, not a production API. +- **`MGPipeApplierState`'s two spellings—the nine table names and `Objects.X`—coexisting** is the deliberate price for leaving ~200 read sites unchanged; the chance to rename comes in the same cut as the twin registry. +- **`g_backendContextGeneration`/`g_syncContextGeneration` and ServerLoop's MakeCurrent deduplication** are as listed in the S4 section, still untouched. -### S6 已落地形状(twin 表按 {session, shareGroup} 键控) +### S6 landed shape (twin tables keyed by {session, shareGroup}) -S5 留下的最后一块:八个后端 twin 表(六个 `StateBackendObjectRegistry`,加 `BackendBufferResourceTable` 与 `BackendSamplerViewTable`)从 `{slot, gen}` 的进程级表变成**按 `{session, shareGroup}` 分桶**的表。这是「两个 nonshared context 的同名 handle」剩下的那一半——applier 的记录已经分开了(S5),但记录指向的 twin 还是一条。 +The last piece S5 left: the eight backend twin tables (the six `StateBackendObjectRegistry`, plus `BackendBufferResourceTable` and `BackendSamplerViewTable`) go from process-level `{slot, gen}` tables to tables **bucketed by `{session, shareGroup}`**. This is the remaining half of "same-named handles in two nonshared contexts"—the applier's records are already separated (S5), but the twin those records point at was still one. -**键结构(`MG_Backend/DirectGLES/DirectGLES.h`)**。`TwinKey{ SessionKey, ShareGroupKey }`,与 applier 的 `MGPipeApplierKey` 是**同一个二元组的后一半**:`SessionKey` 是 `ServerSession*` 的地址(S5 注册时用的也是同一个值,两侧按构造一致),`ShareGroupKey` 走 `MGPipeApplierShareGroupKeyFor(session, currentToken)`——**共享一个函数而不是各写一遍规则**,因为记录与它描述的 twin 必须永远落在同一个桶里,而「0 表示这个 context 自己起了一个组」的第二处拼写正是它们会分开的原因。`{0,0}` 保留给「不属于任何 session 的线程」,也就是被替换掉的进程单例。 +**Key structure** (`MG_Backend/DirectGLES/DirectGLES.h`). `TwinKey{ SessionKey, ShareGroupKey }`, **the second half of the same pair** as the applier's `MGPipeApplierKey`: `SessionKey` is the address of the `ServerSession*` (the same value S5 registers with, so the two sides agree by construction), and `ShareGroupKey` goes through `MGPipeApplierShareGroupKeyFor(session, currentToken)`—**sharing one function instead of writing the rule twice**, because a record and the twin it describes must always land in the same bucket, and a second spelling of "0 means this context started its own group" is exactly how they would come apart. `{0,0}` is reserved for "a thread that belongs to no session", i.e. the process singleton being replaced. -**解析链(`MG_Remote/Server/SessionRuntime.cpp`)**。第三层同构探针:`ResolveThreadTwinKey` 读 `ThreadSessionScope` 装好的 `t_runtime` → `runtime->Session().CurrentContextToken()` → `MGPipeApplierShareGroupKeyFor`;由 `InstallSessionRuntimeHooks` 用 `SetTwinKeyResolver` 装一次(与 S2 的 PipeInputs 探针、S4 的 native tuple 键、S5 的 applier 键并列)。没有探针的线程(monolith、纯客户端、inproc 单进程形状、单元用例)答案恒为 `{0,0}`。**探针只读 server session 侧的状态,不碰 `MG_State`**:`CurrentContextToken()` 是 apply 线程自己维护的原子,`MGPipeApplierShareGroupKeyFor` 读的是 applier 的注册表,所以 apply 线程那条「禁止前端键控查找」的约束(`Managers.h:341/406/430-436`)原样成立。 +**Resolution chain** (`MG_Remote/Server/SessionRuntime.cpp`). The third isomorphic probe: `ResolveThreadTwinKey` reads the `t_runtime` installed by `ThreadSessionScope` → `runtime->Session().CurrentContextToken()` → `MGPipeApplierShareGroupKeyFor`; installed once by `InstallSessionRuntimeHooks` with `SetTwinKeyResolver` (parallel to S2's PipeInputs probe, S4's native tuple key and S5's applier key). On a thread without a probe (monolith, pure client, inproc single-process shape, unit case) the answer is always `{0,0}`. **The probe reads only server-session-side state and does not touch `MG_State`**: `CurrentContextToken()` is an atomic the apply thread maintains itself, and `MGPipeApplierShareGroupKeyFor` reads the applier's registry, so the apply thread's constraint "no frontend keyed lookup" (`Managers.h:341/406/430-436`) stands as written. -**表形状(`SlotTables.h` 的 `SlotTableRegistry`)**。桶是 `SharedPtr>`,按 key 存在一张 unordered_map 里,带一个「上次的 key → 桶」的线程本地 memo(热路径是一次比较)。**~150 个调用点一行没动**:`SlotTableRegistry` 把表上每一个 handle-keyed 入口(`GetOrCreate` / `FindByHandle` / `LiveGenAt` / `HandleOf` / `StateForHandle` / `NoteStateForHandle` / `ReleaseByHandle` / `ForEachLive` / `LiveCount` / 两个 capacity 观测)按**调用线程的桶**转发一遍,所以 `g_backendTextureObjects.FindByHandle(h)` 还是那行字,答的却是本 context 的名字空间;`StateBackendObjectRegistry` 内同样把 `m_slotTable` 换成 `m_slotTables` 并转发。两处刻意的取舍: +**Table shape** (`SlotTables.h`'s `SlotTableRegistry`). A bucket is a `SharedPtr>` stored in an unordered_map by key, with a thread-local memo "last key → bucket" (the hot path is one comparison). **~150 call sites are unchanged**: `SlotTableRegistry` forwards every handle-keyed entry on the table (`GetOrCreate` / `FindByHandle` / `LiveGenAt` / `HandleOf` / `StateForHandle` / `NoteStateForHandle` / `ReleaseByHandle` / `ForEachLive` / `LiveCount` / the two capacity observations) to **the calling thread's bucket**, so `g_backendTextureObjects.FindByHandle(h)` is still that line of text but answers with this context's name space; inside `StateBackendObjectRegistry` `m_slotTable` likewise becomes `m_slotTables` and is forwarded. Two deliberate trade-offs: -- **holder 列表仍是进程级**。notice 是关于**对象**的,不是关于桶的:`OnFrontendObjectDestroyed` / `ReleaseTwinByHandle` 必须走到 fixture 或 context reset 持有的 by-value 拷贝,无论它在哪个桶里——「哪个桶持有它」正是当初造成双 holder 泄漏的那个问题。每个共享 holder 就是一个桶,所以死亡通知天然覆盖全部桶。 -- **`ForEachLive` 走调用线程的桶**,不是全部桶。调用者问的是「我能看见的对象里哪些需要这个」,而它能看见的就是它自己的 share group;遍历全部桶会走到邻居 session 的对象。需要全进程视野的两处(死亡、诊断)走新的 `ForEachBucket(fn)`(回调带 key)。 +- **The holder list stays process-level**. A notice is about the **object**, not the bucket: `OnFrontendObjectDestroyed` / `ReleaseTwinByHandle` must reach the by-value copy held by the fixture or the context reset, whichever bucket it is in—"which bucket holds it" is precisely the problem that caused the double-holder leak. Every shared holder is one bucket, so death notices naturally cover all buckets. +- **`ForEachLive` walks the calling thread's bucket**, not all buckets. The caller asks "which of the objects I can see need this", and what it can see is its own share group; walking all buckets would reach a neighbor session's objects. The two places that need a whole-process view (death, diagnostics) use the new `ForEachBucket(fn)` (the callback carries the key). -**新增的控制面**:`Drop(key)`(一个组)、`DropSession(sessionKey)`(一个 session 的全部组)、`ResetBuckets()`(全部,即 `= {}` 在旧形状下的意思)、`BucketCount()` / `BucketSnapshot()` / `BucketForCallingThread()`(测试与 fixture 的观测面)。`BackendSlotTable::Reset()` 是「把两个空间先移出去再析构」的写法,理由与 `ReleaseTwinAt` 相同:twin 的析构是驱动调用,可能重入 `GetOrCreate`。 +**New control surfaces**: `Drop(key)` (one group), `DropSession(sessionKey)` (all groups of a session), `ResetBuckets()` (all, i.e. what `= {}` meant in the old shape), `BucketCount()` / `BucketSnapshot()` / `BucketForCallingThread()` (observation surfaces for tests and fixtures). `BackendSlotTable::Reset()` is written as "move both spaces out first, then destruct", for the same reason as `ReleaseTwinAt`: a twin's destructor is a driver call and may reenter `GetOrCreate`. -**`DropEveryTwinForEndedServerSession` 变成 per-session**(`Managers.cpp`)。它跑在**正在结束的那个 session 的 apply 线程**上,而 S2 之后同一个进程里可能有别的 session 还在渲染,所以现在是「按调用线程的 session 删它全部桶」;没有 session 的线程(单元用例、`SanityTest` 的 `Transport=Spawn` 形状、fork worker)执行全量清理,与旧形状逐字相同。`g_boundTexturesCache` / `g_boundSamplersCache` / `g_activeTextureUnit` 这三个单元影子仍是进程级、仍在这里整体清空(见下面的欠债)。 +**`DropEveryTwinForEndedServerSession` becomes per-session** (`Managers.cpp`). It runs on **the apply thread of the session that is ending**, and after S2 other sessions in the same process may still be rendering, so it is now "delete all buckets of the calling thread's session"; a thread without a session (unit cases, `SanityTest`'s `Transport=Spawn` shape, fork workers) performs the full cleanup, character for character as the old shape. The three unit shadows `g_boundTexturesCache` / `g_boundSamplersCache` / `g_activeTextureUnit` are still process-level and are still cleared wholesale here (see the debt below). -**`Managers.h:2190` 的注释一并改正**:那里过去写着「a texture is owned by exactly one context (share groups are not implemented)」。真正成立的说法是**texture 属于一个 share group**(S3 的 `ShareGroupState` 持有对象表,S6 之后 twin 表也按组键控),同组两个 context 都会合法地改它;`m_syncedShapeContextId` 因此只是廉价门禁的一半——同组的另一个 context 改了 shape 会 stamp 一个新 id 并(多余地、但安全地)重推一次,而真正兜住变化的是那几个 per-mutation version,它们与 context 无关。 +**The comment at `Managers.h:2190` is corrected as well**: it used to say "a texture is owned by exactly one context (share groups are not implemented)". What really holds is that **a texture belongs to a share group** (S3's `ShareGroupState` holds the object table, and after S6 the twin table is keyed by group as well), and both contexts of a group may legally modify it; `m_syncedShapeContextId` is therefore only half of a cheap gate—another context in the same group changing shape stamps a new id and (redundantly, but safely) re-pushes once, while what really catches the change is the per-mutation versions, which do not depend on the context. -**验收证据**(本次新增): +**Acceptance evidence** (added this commit): -- `MG_Test/Wire/TwinOwnershipTest.cpp`,5 个用例,直接驱动**真实** twin 表(无 EGL、无 wire):同 session 两个不共享的组、同名 handle 是两个 twin 且互不覆盖;同组两个 context 解析**同一个** twin(驱动级共享在 twin 层的等价物——twin 就是持有 driver id 的那个对象);一个 session 的 `DropBucketsOfSession` 只带走自己的 twin,邻居 session 的不受影响;不属于任何 session 的线程仍拿进程级那张表且与 session 的互不串;第六个用例在 `TwinRegistry` 模板(六个注册表同型)上重复前三条并顺带钉住 per-bucket 的世代门禁。 - **负控**(必做):把 `SlotTableRegistry::ForCallingThread` 改成恒答 `{0,0}`(即恢复 S6 前的进程级表),5 个用例里**4 个变红**;`TwoContextsOfOneGroupShareTheGroupsTwins` 保持绿——一个键时两种形状答案相同,这正是该用例断言的是「共享必须发生」而不是「存在两个桶」的原因。改回即全绿。 -- 既有集合零回归:本切片点名的 103 个用例(`EmbeddedServerTest`、`ServerDisplayTest`、`UnixSupervisor`、`InProcessServer`、`SupervisorChildren`、`ServerLoopTest`、`ServerLoopEglTest`、`MultiSessionFixture`、`PeerLatch`、`SurfaceControlFrameTest`、`ContextStateOwnershipTest`、`ApplierOwnershipTest`)全绿,其中 `MultiSessionFixture` 的两个真渲染用例现在跑在按 session 隔离的 twin 表上。 -- **全量 host ctest 与基线的逐名对比**(同 S5 的做法:`git stash push -u -- MobileGL docs` 掉本切片、重建、跑全量留失败名单,恢复后再跑一遍,两份名单按**用例名**`comm` 而不是按行号——本切片多了一个测试文件,行号会整体错位): +- `MG_Test/Wire/TwinOwnershipTest.cpp`, 5 cases, driving the **real** twin tables directly (no EGL, no wire): two nonshared groups in one session—same-named handles are two twins that do not overwrite each other; two contexts of one group resolve **the same** twin (the twin-layer equivalent of driver-level sharing—a twin is the object that holds the driver id); one session's `DropBucketsOfSession` takes only its own twins and leaves the neighbor session's untouched; a thread that belongs to no session still gets the process-level table and does not cross with the sessions'. A sixth case repeats the first three on the `TwinRegistry` template (the six registries are the same shape) and also pins the per-bucket generation gate. + **Negative control** (mandatory): change `SlotTableRegistry::ForCallingThread` to always answer `{0,0}` (i.e. restore the pre-S6 process-level table), and 4 of the 5 cases **go red**; `TwoContextsOfOneGroupShareTheGroupsTwins` stays green—with one key the two shapes answer the same, which is why that case asserts "sharing must happen" rather than "two buckets exist". Switch back and all are green. +- The existing set does not regress: the 103 cases this slice names (`EmbeddedServerTest`, `ServerDisplayTest`, `UnixSupervisor`, `InProcessServer`, `SupervisorChildren`, `ServerLoopTest`, `ServerLoopEglTest`, `MultiSessionFixture`, `PeerLatch`, `SurfaceControlFrameTest`, `ContextStateOwnershipTest`, `ApplierOwnershipTest`) are all green, and two real-rendering cases of `MultiSessionFixture` now run on session-isolated twin tables. +- **Name-by-name comparison of the full host ctest against the baseline** (the same method as S5: `git stash push -u -- MobileGL docs` away this slice, rebuild, run the full suite and keep the failure list; restore and run again; `comm` the two lists by **case name** rather than by line number—this slice added a test file, so line numbers would shift throughout): - | | 数量 | + | | Count | |---|---| - | 基线失败 | 277 | - | 本切片失败 | 278 | - | **本切片新增失败** | **0** | - | 基线失败而本切片不失败 | 0 | + | Baseline failures | 277 | + | This slice's failures | 278 | + | **New failures in this slice** | **0** | + | Baseline failures that this slice does not fail | 0 | - 两份名单的差集只有一个名字:`LogForwardChannel.APeerThatStopsReadingCostsWarnLinesNotTheCallersTime`,它**基线也抖**——同一台机器上单独重复跑,基线 4/60 失败、本切片 2/40 失败,两边的失败断言逐字相同(`LogForwardTest.cpp:446` 的 `Dropped` 行数与 `counters.lossyDropped` 不等、`:448` 的 `counters.notices == 2` 而非 1),是那个用例自己的日志通道竞态:它让对端停止读取然后断言「掉线通知只发一条」,而通知本身由后台线程按队列水位发。该用例不建 backend、不碰 twin,与本切片无关,按既有基线口径记为抖动。其余失败名单全部落在 glslang / 着色器编译族(`ProgramTest` 80、`ProgramInterfaceTest` 32、`AsyncLinkTest` 17、`GlslangCaptureProbeTest` 15、`ShaderCompileAdoptionTest` 14…),与 `3rdparty/glslang` 这个 dirty submodule 的既有基线一致。 + The difference between the two lists is exactly one name: `LogForwardChannel.APeerThatStopsReadingCostsWarnLinesNotTheCallersTime`, which **is also flaky on the baseline**—run alone repeatedly on the same machine, the baseline failed 4/60 and this slice 2/40, with identical failing assertions on both sides (the `Dropped` line count vs `counters.lossyDropped` mismatch at `LogForwardTest.cpp:446`, and `counters.notices == 2` instead of 1 at `:448`), a race in that case's own log channel: it makes the peer stop reading and then asserts "only one disconnect notice is sent", while the notice itself is sent by a background thread according to the queue level. That case builds no backend and touches no twin; it is unrelated to this slice and is recorded as a flake under the existing baseline wording. The remaining failures all fall in the glslang / shader compilation family (`ProgramTest` 80, `ProgramInterfaceTest` 32, `AsyncLinkTest` 17, `GlslangCaptureProbeTest` 15, `ShaderCompileAdoptionTest` 14…), consistent with the existing baseline of the dirty `3rdparty/glslang` submodule. -**S6 明确没做(下一层的账)**: +**What S6 explicitly did not do (the next layer's debt)**: -- **单元影子仍是进程级**:`g_activeTextureUnit`、`g_boundTexturesCache`、`g_boundSamplersCache` 与 sampler cache(`Managers.cpp:11031-11032` 等)是 §3 第 3 条留给 P14b/c 的另一半。它们与 twin 键控**不冲突但也不互补**:缓存做的是指针同一性比较,所以按组分开的 twin 只会让「另一组的 twin」比较不相等并重新绑定(安全方向);真正的残留问题是「同一个 twin 在一次原生 context 切换之后被缓存命中而跳过绑定」,那在 S4 把原生 context 变成 per-context 时就已经存在,属于同一笔账。 -- **驱动级的 `glIsBuffer` 探针仍未弄清**(S4/S5 都记录的同一件事)。S6 因此没有走「真驱动上问一句」那条路,而是按 S5 报告的允许口径在 twin 层断言身份:twin 就是持有 driver id 的对象,两个 context 拿到不同的 twin 就是两个 driver 对象。要做成驱动级证据,需要先把 S4 报告里「同 context 内 `glGenBuffers` 后 `glIsBuffer` 即返回 false」这个探针问题弄清楚。 -- **`g_backendContextGeneration`/`g_syncContextGeneration` 仍是进程级**,同 S4/S5 一节所列。 -- **`MGPipeApplierState` 的两种拼法(`Objects.X` 与表名)仍未收敛**;S5 说「改名的机会在 twin registry 一起做的那一刀」,S6 选择了不动它(那一刀的价值是整洁,而 S6 的 diff 已经在改 8 张表的行为,把重命名捆进来只增风险)。 -- **wire 第 1 条的逐记录 `ContextSlot`** 仍未做。 +- **The unit shadows are still process-level**: `g_activeTextureUnit`, `g_boundTexturesCache`, `g_boundSamplersCache` and the sampler cache (`Managers.cpp:11031-11032` etc.) are the other half that §3 item 3 leaves to P14b/c. They **neither conflict with nor complement** the twin keying: the caches compare pointer identity, so twins separated by group only make "the other group's twin" compare unequal and rebind (the safe direction); the real residual problem is "the same twin is hit by the cache after a native context switch and the bind is skipped", which already existed when S4 made the native context per-context and belongs to the same debt. +- **The driver-level `glIsBuffer` probe is still unsolved** (the same thing S4/S5 recorded). S6 therefore did not take the "ask the real driver" route, and instead asserted identity at the twin layer under the allowance of the S5 report: a twin is the object holding the driver id, so two contexts getting different twins means two driver objects. Making it driver-level evidence requires first solving the probe problem from the S4 report ("`glIsBuffer` returns false right after `glGenBuffers` in the same context"). +- **`g_backendContextGeneration`/`g_syncContextGeneration` are still process-level**, as listed in the S4/S5 sections. +- **`MGPipeApplierState`'s two spellings (`Objects.X` and the table names) are still not converged**; S5 said "the chance to rename comes in the same cut as the twin registry", and S6 chose not to touch it (that cut's value is tidiness, while S6's diff already changes the behavior of 8 tables; bundling a rename in would only add risk). +- **Wire item 1's per-record `ContextSlot`** is still not done. -## 分期与验收 +## Phases and acceptance -| 期 | 内容 | 验收 | +| Phase | Content | Acceptance | |---|---|---| -| P14a | wire context 身份 + 前端 GLContext/ShareGroupState 拆分 + CreateContext/DestroyContext 上 wire | shared contexts 访问同一 buffer/texture;nonshared 同名资源隔离;每 context 的 viewport/FBO/bindings/error 独立;context 跨线程移交后状态保留 | -| P14b | 后端 per-context native tuple + surface 生命周期 | pbuffer→window→pbuffer 资源不丢;Qt offscreen probe + 实窗的 context 序列不丢首窗内容 | -| P14c | server 同进程多 session(registry、per-session applier/apply-thread/反向路由),移除 fork-worker 依赖 | 相同 handle 值的两个 session 隔离且可独立关闭;一个 session 崩不拖死另一个;in-process server 并发两 client 渲染互不串台 | -| P14d | anland 切统一 embedded server | KWin(OnScreen session)+ Konsole(Offscreen session)同 server 同上屏;见交接文档验收链 | +| P14a | wire context identity + frontend GLContext/ShareGroupState split + CreateContext/DestroyContext on the wire | shared contexts access the same buffer/texture; nonshared same-named resources are isolated; per-context viewport/FBO/bindings/error are independent; state survives a context handover across threads | +| P14b | backend per-context native tuple + surface lifetime | pbuffer→window→pbuffer loses no resources; the Qt offscreen probe + real-window context sequence does not lose the first window's content | +| P14c | server multiple sessions in one process (registry, per-session applier/apply-thread/reverse routing), removing the fork-worker dependency | two sessions with the same handle values are isolated and can be closed independently; one session crashing does not drag the other down; the in-process server renders two concurrent clients without cross talk | +| P14d | anland switches to the unified embedded server | KWin (OnScreen session) + Konsole (Offscreen session) on the same server, both presented on screen; see the acceptance chain in the handover document | -每期都过既有门:host ctest 全量、`split_coverage.py` 三臂、monolith G1 符号不变;wire 变更期两端同 stamp 重构建。monolith 路径(`MOBILEGL_PIPE_PUSH=0`)下多 context 语义同样必须成立——拆分前后端共用一个 `MG_State`。 +Every phase passes the existing gates: the full host ctest, `split_coverage.py`'s three arms, the unchanged monolith G1 symbols; in a phase with wire changes both ends rebuild with the same stamp. Multi-context semantics must also hold on the monolith path (`MOBILEGL_PIPE_PUSH=0`)—before and after the split both ends share one `MG_State`. -## 明确不做 +## Explicitly not done -- 跨 session 共享 GL 对象(EGL 语义本就不允许跨连接共享;需要时另立 import 设计)。 -- per-context ring(见 wire 1 的取舍)。 -- 把 FBO/VAO 等容器对象放进 share group。 -- 保留 `--serve --max-sessions` 的 fork 分发作为任何验收路径;工具本身可留作调试,但 anland 与多 session 验收不得依赖它。 +- Sharing GL objects across sessions (EGL semantics do not allow sharing across connections anyway; if needed, a separate import design). +- per-context ring (see the trade-off in wire 1). +- Putting container objects such as FBO/VAO into the share group. +- Keeping `--serve --max-sessions`'s fork dispatch as any acceptance path; the tool itself may stay for debugging, but anland and multi-session acceptance must not depend on it. diff --git a/docs/Disaggregated/guide/build-and-run.md b/docs/Disaggregated/guide/build-and-run.md index 9e4f1493..a1a5a043 100644 --- a/docs/Disaggregated/guide/build-and-run.md +++ b/docs/Disaggregated/guide/build-and-run.md @@ -1,39 +1,39 @@ -# 构建、运行与测试 +# Build, run and test -> 上手说明。文档导航见 [`../README.md`](../README.md);全部开关见 [`../design/09-build-switches-counters.md`](../design/09-build-switches-counters.md) 附 A。 +> Getting started. For the documentation index see [`../README.md`](../README.md); for every switch see [`../design/09-build-switches-counters.md`](../design/09-build-switches-counters.md) appendix A. -## 三种构建 +## Three builds -P13 起只有一种单进程形态:后端只从前端推来的记录取状态(记录臂),旧的「后端直接读前端」路径与 pull / push 两套构建一起删掉了(`MOBILEGL_PIPE_PUSH` 不再是 CMake 选项)。 +Since P13 there is only one single-process shape: the backend takes its state solely from the records the frontend pushes (the record arm); the old "backend reads the frontend directly" path went away together with the pull / push builds (`MOBILEGL_PIPE_PUSH` is no longer a CMake option). -| 构建目录 | CMake | 用途 | +| Build directory | CMake | Purpose | |---|---|---| -| `build-linux` | 默认 | 出货形态(FCL 内嵌库就是它):单进程,记录臂,不编 `MG_Remote` | -| `build-verify` | `-DMOBILEGL_PIPE_VERIFY=ON` | 每个 draw 把推来的状态与前端实际状态逐字段比对;慢,永不出货 | -| `build-split` | `-DMOBILEGL_BUILD_DISAGGREGATED=ON -DMOBILEGL_BUILD_DISAGGREGATED_INPROC=ON` | 可以拆成两线程 / 两进程 / 两台机器;不设 `MOBILEGL_TRANSPORT` 时是同一记录臂的单进程对照 | +| `build-linux` | default | The shipped shape (the FCL embedded library is this one): single process, record arm, `MG_Remote` not built | +| `build-verify` | `-DMOBILEGL_PIPE_VERIFY=ON` | Every draw compares the pushed state field by field with the frontend's actual state; slow, never shipped | +| `build-split` | `-DMOBILEGL_BUILD_DISAGGREGATED=ON -DMOBILEGL_BUILD_DISAGGREGATED_INPROC=ON` | Can split into two threads / two processes / two machines; with `MOBILEGL_TRANSPORT` unset it is the single-process control on the same record arm | -库由七个 OBJECT 模块拼成(`mg_util` / `mg_pipe` / `mg_backend` / `mg_frontend` / `mg_remote_transport` / `mg_remote_client` / `mg_remote_server`,按 `scripts/link_ratchet.py` 的 PARTITION 划分);split 构建另有 `MobileGL_server_linkcheck`,证明 server 那一半不带前端模块也能链接(剩下的前端引用是 link ratchet 基线里具名的债务)。 +The library is assembled from seven OBJECT modules (`mg_util` / `mg_pipe` / `mg_backend` / `mg_frontend` / `mg_remote_transport` / `mg_remote_client` / `mg_remote_server`, partitioned by `scripts/link_ratchet.py`); the split build also has `MobileGL_server_linkcheck`, which proves the server half links without the frontend modules (the remaining frontend references are named debts in the link-ratchet baseline). -## 选拓扑 +## Choosing a topology -split 构建在运行时用 `MOBILEGL_TRANSPORT` 选拓扑;**不设就是单进程(monolith)对照**: +The split build selects the topology at run time with `MOBILEGL_TRANSPORT`; **unset means the single-process (monolith) control**: -| `MOBILEGL_TRANSPORT` | 形态 | +| `MOBILEGL_TRANSPORT` | Shape | |---|---| -| 不设 / `monolith` | 单线程直调 | -| `inproc` | 同一进程两个线程(CI 的主验收形态) | -| `spawn` | 两个进程;再用 `MOBILEGL_IPC_CONTROL`(`fork` / `unix:` / `tcp://host:port`)与 `MOBILEGL_IPC_DATA`(`auto` / `shm` / `stream`)选控制面与数据面,跨机时还要 `MOBILEGL_IPC_TOKEN`(≥16 字节) | +| unset / `monolith` | Single thread, direct calls | +| `inproc` | Two threads in one process (the main CI acceptance shape) | +| `spawn` | Two processes; `MOBILEGL_IPC_CONTROL` (`fork` / `unix:` / `tcp://host:port`) and `MOBILEGL_IPC_DATA` (`auto` / `shm` / `stream`) then choose the control and data planes; across machines also set `MOBILEGL_IPC_TOKEN` (at least 16 bytes) | ```text MOBILEGL_TRANSPORT=inproc MOBILEGL_ITEST_REQUIRE_GPU=1 ctest --test-dir build-split -L integration-split --output-on-failure -ctest --test-dir build-split -L 'integration-(spawn|tcp)' --output-on-failure # 条目自带 spawn / tcp 环境与私有日志 +ctest --test-dir build-split -L 'integration-(spawn|tcp)' --output-on-failure # the entries carry their own spawn / tcp environment and private logs ``` -其他常用旋钮:`MOBILEGL_IPC_RUN_AHEAD`(默认 1,client 发完就走)、`MOBILEGL_IPC_STAGE_MB`(默认 32,其 1/4 是大块上传的分块预算)、`MOBILEGL_IPC_SURFACE=server`(使用 Android server 自己的窗口)、`MOBILEGL_PIPE_STATS=1`(边界计数器,日志里的 `MGPipe stats:` 行)。 +Other common knobs: `MOBILEGL_IPC_RUN_AHEAD` (default 1, the client sends and moves on), `MOBILEGL_IPC_STAGE_MB` (default 32; a quarter of it is the chunk budget for large uploads), `MOBILEGL_IPC_SURFACE=server` (use the Android server's own window), `MOBILEGL_PIPE_STATS=1` (boundary counters, the `MGPipe stats:` lines in the log). ## Android -- 两份 APK flavour:单进程 / split(Gradle 属性 `mobilegl.buildDisaggregated`、`mobilegl.buildDisaggregatedInproc`;独立 plugin 构建默认 split,FCL 内嵌默认单进程)。split APK 同样要设 `MOBILEGL_TRANSPORT`,不设就是单进程对照。 -- 设备侧 server 有两种形态:离屏的前台 Service(`MobileGLServerService`)与上屏的 `MobileGLDisplayActivity`;同一时刻只有一个。plugin 与 trace 两个 flavour 的 APK 都带(standalone 构建默认开 `mobilegl.buildDisaggregated`),入口是 APK 底部导航栏的 “Render Server” 页;plugin flavour 的这三个组件不导出,只有 trace 允许 adb 直接按组件名拉起。 -- 电脑当 client、手机当 server 的跨机配置(起 server、设令牌、`adb forward` 备用路线)见 git 历史中的"两边怎么配"。 -- 性能对比只用 Redmi `2f7cbe2e`,按 [`pin-verification-2026-09-07.md`](pin-verification-2026-09-07.md) 定频,reboot-clean、同热窗口、配对 A/B。P13 之后的性能工作以 `dev` 分支构建为「之前」基线(用户 2026-10-07)。 +- Two APK flavors: single-process / split (Gradle properties `mobilegl.buildDisaggregated`, `mobilegl.buildDisaggregatedInproc`; a standalone plugin build defaults to split, the FCL embedding defaults to single-process). The split APK also needs `MOBILEGL_TRANSPORT`; unset means the single-process control. +- The on-device server has two shapes: an off-screen foreground Service (`MobileGLServerService`) and the on-screen `MobileGLDisplayActivity`; only one at a time. Both the plugin and trace flavor APKs carry them (standalone builds enable `mobilegl.buildDisaggregated` by default); the entry point is the "Render Server" page in the APK's bottom navigation. In the plugin flavor these three components are not exported; only the trace build allows adb to start them directly by component name. +- For the cross-machine setup with the computer as client and the phone as server (starting the server, setting the token, the `adb forward` fallback), see "configuring the two sides" in the phase notes (in git history). +- Performance comparisons use only the Redmi `2f7cbe2e`, pinned as described in the pin-verification record (in git history): reboot-clean, same thermal window, paired A/B. Performance work after P13 uses the `dev` build as its "before" baseline (user, 2026-10-07). diff --git a/docs/Disaggregated/guide/code-map.md b/docs/Disaggregated/guide/code-map.md index f1c1b569..8fddb235 100644 --- a/docs/Disaggregated/guide/code-map.md +++ b/docs/Disaggregated/guide/code-map.md @@ -1,14 +1,14 @@ -# 代码地图 +# Code map -> 参考。文档导航见 [`../README.md`](../README.md);目录布局与构建选项见 [`../design/09-build-switches-counters.md`](../design/09-build-switches-counters.md) §16。 +> Reference. For the documentation index see [`../README.md`](../README.md); for the directory layout and build options see [`../design/09-build-switches-counters.md`](../design/09-build-switches-counters.md) §16. -| 路径 | 作用 | +| Path | Role | |---|---| -| `MobileGL/MG_Pipe/` | 接口本身:调用目录 `PipeCalls.def` 与其他 `.def` 表、payload / 句柄 / 回调头、`PipeApply`、`PipeRoute`、`generated/*.inc`(生成物,提交进树) | -| `MobileGL/MG_Impl/Pipe/` | 前端:Tracker、`PipeFill`、`SlotAllocator`、`CsoCache`、`CompositeResolver`、`ResourceTracker`、各族 `*Emit.h` | -| `MobileGL/MG_Backend/MGPipe/` | `PipeInputs`:后端读的、被前端推来的状态块 | -| `MobileGL/MG_Remote/` | 拆分专用(仅 `MOBILEGL_BUILD_DISAGGREGATED`):`Protocol/`(控制面 schema)、`Transport/`(控制面 `ITransport` × 数据面 `ILink`)、`Wire/`(记录编解码)、`Client/`、`Server/`;各阶段的 wire 契约 `CONTRACT-*.md` | -| `MobileGL/MG_Util/Metrics/PipeStats.{h,cpp}` | 边界计数器(`MOBILEGL_PIPE_STATS=1`) | -| `MobileGL/MG_Test/Pipe/`、`MG_Test/Wire/`、`MG_IntegrationTest/Harness/*Peek` | 目录 / tracker / 发射器单元测试、wire 与 remote 单元测试、白盒断言 | -| `scripts/` | 生成器(`gen_pipe.py`、`gen_pipe_field_ownership.py`、`gen_pipe_dirty_surface.py`、`gen_protocol.py`)、门脚本(`symbol_report.py`、`check_include_closure.py`、`link_ratchet.py`、G5 保护区脚本、`check_doc_citations.py`)、`ci/` | -| `tools/trace_replay/`、`tools/device_bench/` | trace 回放(含 TCP 矩阵跑器)、设备定频与配对 A/B 工具 | +| `MobileGL/MG_Pipe/` | The interface itself: the call catalog `PipeCalls.def` and the other `.def` tables, the payload / handle / callback headers, `PipeApply`, `PipeRoute`, `generated/*.inc` (generated, committed to the tree) | +| `MobileGL/MG_Impl/Pipe/` | Frontend: Tracker, `PipeFill`, `SlotAllocator`, `CsoCache`, `CompositeResolver`, `ResourceTracker`, the per-family `*Emit.h` | +| `MobileGL/MG_Backend/MGPipe/` | `PipeInputs`: the state block the backend reads and the frontend pushes | +| `MobileGL/MG_Remote/` | Split-only (`MOBILEGL_BUILD_DISAGGREGATED`): `Protocol/` (control-plane schema), `Transport/` (control plane `ITransport` × data plane `ILink`), `Wire/` (record encoding and decoding), `Client/`, `Server/`; the per-phase wire contracts `CONTRACT-*.md` | +| `MobileGL/MG_Util/Metrics/PipeStats.{h,cpp}` | Boundary counters (`MOBILEGL_PIPE_STATS=1`) | +| `MobileGL/MG_Test/Pipe/`, `MG_Test/Wire/`, `MG_IntegrationTest/Harness/*Peek` | Catalog / tracker / emitter unit tests, wire and remote unit tests, white-box assertions | +| `scripts/` | Generators (`gen_pipe.py`, `gen_pipe_field_ownership.py`, `gen_pipe_dirty_surface.py`, `gen_protocol.py`), gate scripts (`symbol_report.py`, `check_include_closure.py`, `link_ratchet.py`, the G5 protected-region scripts, `check_doc_citations.py`), `ci/` | +| `tools/trace_replay/`, `tools/device_bench/` | Trace replay (including the TCP matrix runner), device clock pinning and paired A/B tooling | diff --git a/docs/Disaggregated/guide/discipline.md b/docs/Disaggregated/guide/discipline.md index f715debf..c7f15880 100644 --- a/docs/Disaggregated/guide/discipline.md +++ b/docs/Disaggregated/guide/discipline.md @@ -1,21 +1,21 @@ -# 工程纪律与验证门 +# Engineering discipline and verification gates -> 参考。验证门的设计见 [`../design/07-memory-readback-verification.md`](../design/07-memory-readback-verification.md) §13.2;各阶段实际跑门的结果在 `../notes/<阶段>/README.md`。 +> Reference. The design of the verification gates is in [`../design/07-memory-readback-verification.md`](../design/07-memory-readback-verification.md) §13.2; the per-phase gate results are in the phase notes (in git history). -## 每个提交 +## Every commit -- 默认 ALL target 必须完整构建;禁止提交热路径插桩(CI grep 门)。 -- **每个门必须能因它存在的理由变红**:带阴性对照并真跑过一次红(R-16);公共 GL 看不见的改用白盒断言。 -- 正确性门是硬门;**性能只记录、不设门**(用户 2026-09-08),但数字必须真的采到。专门的优化阶段排在路线图推完之后;P13 之后的性能轮以 `dev` 构建为基线(用户 2026-10-07)。 -- **拆分不顺手修 `dev` 的 bug**:发现的 `dev` 侧缺陷记成独立条目、独立 PR。 +- The default ALL target must build completely; instrumenting hot paths is not allowed in commits (a CI grep gate). +- **Every gate must be able to turn red for the reason it exists**: it has a negative control and has really run red once (R-16); what public GL cannot see is asserted white-box instead. +- Correctness gates are hard gates; **performance is recorded, not gated** (user, 2026-09-08), but the numbers must actually be measured. Dedicated optimization phases come after the roadmap; performance rounds after P13 use the `dev` build as the baseline (user, 2026-10-07). +- **Do not fix `dev` bugs along the way**: a defect found on the `dev` side becomes its own entry and its own PR. -## 每个阶段出口 +## Every phase exit -- 跑一次五部分门:接口纯度、语义影子比对、行为 A/B、性能记录、覆盖与句柄纪律。 -- 字节 / 名字级等式:**G5** 受保护区域逐字节一致;**G14** 测试名只增不删。**G1**(pull 构建的符号集与 `.text` 对基线恒等)与 **G2**(pull 与 push 的测试名集合相同)随 pull 构建在 P13 退役;接班的是:出货库零 `MG_Remote` 符号检查、skip 普查(新出现的跳过与消失的名字都要在基线里具名)、recorder 金标(`MG_Test/Pipe/RecorderGoldenTest.cpp`:固定 GL 调用序列的记录流逐条比对,改金标要在提交里说为什么),以及 link ratchet(server 一半对前端的引用只减不增,不允许 `# P13` 注解)。 -- 性能判据是**逐线程 CPU 时间**;设备对比走 reboot-clean + 同热窗口配对 A/B,只用 Redmi `2f7cbe2e`([`pin-verification-2026-09-07.md`](pin-verification-2026-09-07.md));Windows 机器不是正确性门。 -- 收官由异模型族审查一次,发现进入下一阶段首轮;实现方与审查方错开模型族;不过度验证(用户 2026-09-16,ID-66)。 +- Run the five-part gate once: interface purity, semantic shadow comparison, behavioral A/B, performance record, coverage and handle discipline. +- Byte and name level equalities: **G5** protected regions are byte-identical; **G14** test names only grow. **G1** (the pull build's symbol set and `.text` identical to the baseline) and **G2** (the pull and push builds have the same set of test names) retired with the pull build in P13; their successors are: the zero-`MG_Remote`-symbol check on the shipped library, the skip census (newly appearing skips and disappearing names must be named in the baseline), the recorder golden (`MG_Test/Pipe/RecorderGoldenTest.cpp`: record streams from a fixed GL call sequence compared one by one; changing the golden requires saying why in the commit), and the link ratchet (the server half's references to the frontend only fall, and `# P13` annotations are not allowed). +- The performance criterion is **per-thread CPU time**; device comparisons use reboot-clean + same-thermal-window paired A/B, on the Redmi `2f7cbe2e` only (pin-verification record, in git history); a Windows machine is not a correctness gate. +- The close-out is reviewed once by a different model family; findings enter the first round of the next phase; implementers and reviewers use different model families; do not over-verify (user, 2026-09-16, ID-66). ## CTS -`gl44to46` 约 56,271 例,单独计价:逐阶段只跑该阶段可能影响的具名块;完整 caselist 只在架构边界与合并 `dev` 之前跑,放 CI 不放关键路径。 +`gl44to46` has about 56,271 cases and is priced separately: each phase runs only the named blocks it can affect; the full caselist runs only at architecture boundaries and before merging into `dev`, in CI rather than on the critical path. diff --git a/docs/Disaggregated/guide/embedded-server.md b/docs/Disaggregated/guide/embedded-server.md index e840777e..68a2397f 100644 --- a/docs/Disaggregated/guide/embedded-server.md +++ b/docs/Disaggregated/guide/embedded-server.md @@ -1,49 +1,59 @@ -# 在宿主 APK 中嵌入 split server +# Embedding the split server in a host APK -宿主应用可直接加载 `libMobileGL.so`,把自己持有的 `ANativeWindow` 交给 server。 -窗口、输入和 Android Service 的生命周期由宿主 APK 管理;不需要安装 MobileGL plugin APK。 -公共接口是 [`EmbeddedServer.h`](../../../MobileGL/MG_Remote/Server/EmbeddedServer.h), -只使用 C 类型,也可通过 `dlsym` 调用。构建必须开启 `MOBILEGL_BUILD_DISAGGREGATED`。 +A host application can load `libMobileGL.so` directly and hand the server an `ANativeWindow` it owns. +The window, input and the Android Service lifecycle stay with the host APK; no MobileGL plugin APK is +needed. The public interface is +[`EmbeddedServer.h`](../../../MobileGL/MG_Remote/Server/EmbeddedServer.h), uses only C types, and can +also be called through `dlsym`. The build must enable `MOBILEGL_BUILD_DISAGGREGATED`. -## 有窗口的合成器服务 +## Compositor service with a window -在加载库前设置 `MOBILEGL_IPC_ROLE=server`、`MOBILEGL_IPC_DIAL=no`,清除 -`MOBILEGL_TRANSPORT`、`MOBILEGL_IPC_SERVER_PATH`、`MOBILEGL_IPC_RING_MB` 和 -`MOBILEGL_IPC_STAGE_MB`。建议放在宿主 APK 的独立服务进程中,以免渲染故障结束 UI 进程。 +Before loading the library, set `MOBILEGL_IPC_ROLE=server` and `MOBILEGL_IPC_DIAL=no`, and clear +`MOBILEGL_TRANSPORT`, `MOBILEGL_IPC_SERVER_PATH`, `MOBILEGL_IPC_RING_MB` and +`MOBILEGL_IPC_STAGE_MB`. Running in a separate service process of the host APK is recommended, so that +a rendering fault does not take down the UI process. -1. 调用 `mobilegl_server_display_install_android(request_geometry, user)`。 - 回调可为空;有回调时,它在 apply 线程运行,必须快速返回,把尺寸变更交给宿主线程。 -2. 从宿主的 `Surface` 获取 `ANativeWindow`,调用 - `mobilegl_server_display_attach_android(window, width, height)`。 - server 独立持有引用,调用者随后释放自己的引用。同一窗口再次 attach 只更新尺寸。 -3. 在服务线程调用 `mobilegl_server_serve_inprocess("@anland-mobilegl-compositor")`。 - 这会在当前进程接受一个 client 会话。AF_UNIX 控制连接用 `SCM_RIGHTS` 传递共享内存段, - 数据通过 SHM 环传输。客户端设置 `MOBILEGL_TRANSPORT=spawn`、 - `MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl-compositor`、`MOBILEGL_IPC_DATA=shm` 和 - `MOBILEGL_IPC_SURFACE=server`。 -4. Surface 销毁时调用 `mobilegl_server_display_detach(3000)`。 - 返回值 `0/1/2/3` 分别为无窗口、直接释放、会话释放后完成、超时。 - 超时会保留引用,直到 apply 线程停止使用窗口;当前失窗会结束活动会话。 -5. 服务停止时调用 `mobilegl_server_stop_inprocess()`,等待 serve 线程返回,再调用 - `mobilegl_server_display_uninstall(3000)`。几何回调的 user 对象应至少活到此时。 +1. Call `mobilegl_server_display_install_android(request_geometry, user)`. + The callback may be null; when present it runs on the apply thread, must return quickly, and hands + size changes to the host thread. +2. Take an `ANativeWindow` from the host's `Surface` and call + `mobilegl_server_display_attach_android(window, width, height)`. + The server holds its own reference; the caller then releases its own. Attaching the same window + again only updates the size. +3. On the service thread, call `mobilegl_server_serve_inprocess("@anland-mobilegl-compositor")`. + This accepts one client session in the current process. The AF_UNIX control connection passes the + shared-memory segment with `SCM_RIGHTS`, and data travels over a SHM ring. The client sets + `MOBILEGL_TRANSPORT=spawn`, `MOBILEGL_IPC_CONTROL=unix:@anland-mobilegl-compositor`, + `MOBILEGL_IPC_DATA=shm` and `MOBILEGL_IPC_SURFACE=server`. +4. When the Surface is destroyed, call `mobilegl_server_display_detach(3000)`. + The return values `0/1/2/3` mean no window, released directly, completed after the session + released it, and timed out. On timeout the reference is kept until the apply thread stops using the + window; losing the window currently ends the active session. +5. When the service stops, call `mobilegl_server_stop_inprocess()`, wait for the serve thread to + return, then call `mobilegl_server_display_uninstall(3000)`. The geometry callback's user object + must live at least until then. -`width/height` 为零时,Android attach 从 `ANativeWindow` 查询尺寸。几何回调收到正尺寸表示 -请求固定缓冲尺寸,收到 `0/0` 表示恢复宿主布局尺寸;宿主应通过后续 attach 报告实际结果。 -安装、attach、detach 和 uninstall 由宿主串行调用。库拒绝替换已安装的 display 或尚未结束 -的旧窗口租约,避免晚到的释放使用另一组引用回调。 +When `width/height` are zero, the Android attach queries the size from the `ANativeWindow`. A positive +size in the geometry callback requests fixed buffer dimensions; `0/0` means restore the host's layout +size, and the host reports the actual result through a later attach. Install, attach, detach and +uninstall are serialized by the host. The library refuses to replace an installed display or an old +window lease that has not ended, so that a late release cannot use another set of reference callbacks. -## 并发的离屏应用服务 +## Concurrent off-screen application service -一个进程仍只有一套 backend/GL 状态。有窗口的服务只接一个合成器;其他 EGL client 可连接 -宿主 APK 打包的 `libMobileGLServer.so` 可执行文件,由另一个服务进程负责启动和结束: +A process still has only one set of backend / GL state. A service with a window accepts a single +compositor; other EGL clients can connect to the `libMobileGLServer.so` executable packaged by the +host APK, which another service process starts and stops: ```text /libMobileGLServer.so @anland-mobilegl --serve --max-sessions 16 ``` -`--max-sessions` 是活动会话上限,接受 `1..64`,默认仍为 `1`。大于 `1` 只适用于 -AF_UNIX 的 `--serve` 离屏 supervisor。每个 client 单独 fork worker,拥有独立 backend, -共享内存与其他会话隔离;worker 退出后归还名额,supervisor 结束时所有 worker 一起结束。 -这些 worker 没有 display,客户端应清除 `MOBILEGL_IPC_SURFACE`,由客户端 WSI 提交窗口图像。 +`--max-sessions` is the limit on active sessions; it accepts `1..64` and still defaults to `1`. Values +above `1` apply only to the AF_UNIX `--serve` off-screen supervisor. Each client forks its own worker +with an independent backend, isolated from other sessions in shared memory; a worker returning frees +its slot, and all workers end when the supervisor ends. These workers have no display; the client +should clear `MOBILEGL_IPC_SURFACE` and submit window images through its own WSI. -进程隔离解决多个应用同时连接的问题;同一应用中的真正多 context/share-group 支持仍需另行实现。 +Process isolation solves multiple applications connecting at the same time; true multi-context / +share-group support inside one application still needs separate work. diff --git a/docs/Disaggregated/guide/glossary.md b/docs/Disaggregated/guide/glossary.md index b44c2c79..f6ab89b7 100644 --- a/docs/Disaggregated/guide/glossary.md +++ b/docs/Disaggregated/guide/glossary.md @@ -1,23 +1,23 @@ -# 术语 +# Terms -> 参考。文档导航见 [`../README.md`](../README.md)。 +> Reference. For the documentation index see [`../README.md`](../README.md). -| 术语 | 意思 | +| Term | Meaning | |---|---| -| 前端 / 后端 | 前端 = `MG_State` + `MG_Impl`,处理应用的 GL 调用;后端 = `MG_Backend`,真正调用驱动 | -| Espryt / Magma | 两个后端:Espryt 走 OpenGL ES(DirectGLES),Magma 走 Vulkan(DirectVulkan) | -| client / server | 拆分后的前端角色 / 后端角色;可以是两个线程、两个进程或两台机器 | -| monolith / inproc / spawn | 三种拓扑:单线程直调 / 同进程两线程 / 两个进程(可跨机) | -| pull / push | 后端自己去读前端状态(旧做法)/ 前端把状态推给后端(MGPipe) | -| verb | 会让后端真正做事的命令:draw、dispatch、clear、blit、回读、XFB、query、纹理操作。状态只在 verb 之前推送 | -| 句柄 `{slot, gen}` | 对象的身份:client 分配的槽号 + 复用代数,server 从不回传 | -| CSO | 常量状态对象(渲染状态、顶点格式、sampler、sampler view、shader):client 按内容去重,server 按句柄缓存 | -| 控制面 / 数据面 | 握手与罕见控制消息走的连接 / 命令记录与批量数据走的通道;两者可分别选(共享内存或字节流、本机或 TCP) | -| lockstep / run-ahead | client 每条命令都等 server 做完 / client 发完就走,只有需要答案的命令才等 | -| barrier tax | 拆成两线程后多出来的逐线程 CPU 代价(split − push) | -| device-lost | server 崩溃或断线后 client 进入的状态:GL 调用变空操作、交换缓冲返回"上下文丢失",而不是崩溃或卡死 | -| class A / B / C | 后端函数表的槽:A 本地回答,B 发成记录,C 还没迁移、按名拒绝 | -| Track V / Track H | 值类读点的迁移(整块数据过线)/ 对象类读点的迁移(对象指针换成句柄) | -| G1 / G2 / G5 / G14 | 验证门:单进程构建二进制逐字节不变 / pull 与 push 测试名集合相同 / 受保护的后端函数逐字节不变 / 测试名只增不删 | -| red-once(R-16) | 每个门都必须真的跑红过一次,证明它能因为它要抓的问题而失败 | -| `MGGen` | server 私有的"我重建了驱动对象"纪元,永不过线;与句柄代数严格分开 | +| frontend / backend | frontend = `MG_State` + `MG_Impl`, handling the application's GL calls; backend = `MG_Backend`, calling the driver for real | +| Espryt / Magma | The two backends: Espryt goes through OpenGL ES (DirectGLES), Magma through Vulkan (DirectVulkan) | +| client / server | The frontend role / backend role after the split; they can be two threads, two processes or two machines | +| monolith / inproc / spawn | The three topologies: single thread direct calls / two threads in one process / two processes (optionally across machines) | +| pull / push | The backend reads the frontend's state itself (the old way) / the frontend pushes state to the backend (MGPipe) | +| verb | A command that makes the backend actually do work: draw, dispatch, clear, blit, readback, XFB, query, texture operations. State is pushed only before a verb | +| handle `{slot, gen}` | An object's identity: a client-allocated slot plus the reuse generation; the server never sends it back | +| CSO | Constant state object (render state, vertex format, sampler, sampler view, shader): the client deduplicates by content, the server caches by handle | +| control plane / data plane | The connection carrying the handshake and rare control messages / the channel carrying command records and bulk data; each can choose shared memory or a byte stream, local or TCP | +| lockstep / run-ahead | The client waits for the server after every command / the client sends and moves on, waiting only for commands that need an answer | +| barrier tax | The extra per-thread CPU cost of splitting into two threads (split − push) | +| device-lost | The state the client enters after the server crashes or disconnects: GL calls become no-ops and swap buffers returns "context lost" instead of crashing or hanging | +| class A / B / C | Slots in the backend function table: A answers locally, B becomes a record, C is not migrated yet and is refused by name | +| Track V / Track H | Migration of value-class read points (a whole block crosses the wire) / migration of object-class read points (object pointers become handles) | +| G1 / G2 / G5 / G14 | Verification gates: single-process build binary byte-identical / pull and push have the same test-name set / protected backend functions byte-identical / test names only grow | +| red-once (R-16) | Every gate must really have run red once, proving it can fail for the problem it is meant to catch | +| `MGGen` | The server's private "I rebuilt the driver object" epoch; it never crosses the wire and is kept strictly separate from the handle generation | diff --git a/docs/Disaggregated/pwait/README.md b/docs/Disaggregated/pwait/README.md index 452e75d4..e4386667 100644 --- a/docs/Disaggregated/pwait/README.md +++ b/docs/Disaggregated/pwait/README.md @@ -6,7 +6,7 @@ thread records and applies. Inproc: the GL thread records and `mgl-srv-apply` ap The timelines and latency below come from one 4.9 s Perfetto run per arm (`pwlat`, with frametimeline). The fps numbers come from the 3-rep A/B in SCOREBOARD.md (section pwab). -The mechanism is analysed in depth in PRESENT-WAIT.md. +The mechanism is analyzed in depth in PRESENT-WAIT.md. ## Summary @@ -264,7 +264,7 @@ the display. Both are separate decisions and are not measured here. images, and a request of 7 (extra 2) gives 7 (logcat "Swapchain created ... imageCount", all runs). The platform rounds the MAILBOX request up to at least 6, so extra=2 is only one image more than the default. extra=1 would probably give no change; that was not run. -- **Memory:** each image costs a full-size RGBA8 colour buffer plus a D24S8 depth/stencil buffer of the +- **Memory:** each image costs a full-size RGBA8 color buffer plus a D24S8 depth/stencil buffer of the same size (Magma's default framebuffer has one per image). At FCL's 1280x800 surface in these runs that is about 4.1 + 4.1 = 8.2 MB per image. At a native 2560x1600 surface it would be about 33 MB. Driver compression metadata adds a little. @@ -317,7 +317,7 @@ Nothing outside the throttle moved: frame = CPU + throttle still holds (2.43 + 0 - The +24 % bound came from the older traces' CPU of 2.86-2.9 ms (3.60 -> 2.9). At this baseline the presenting-thread CPU is 2.39 ms (reps) or 2.49 ms (trace). So removing the throttle alone allows up to +32 % (trace: 3.29 -> 2.49). -- The after arm also has lever A, and A did more than modelled. The model charged the window pass a full +- The after arm also has lever A, and A did more than modeled. The model charged the window pass a full 0.8 ms start latency plus the pass, about 0.95 ms after the release. Measured E-R is 0.69 ms, so the start for the small final batch is shorter than for a whole-frame batch. The GPU-after-release wait fell from 0.50 to 0.11 ms per frame. The display-before-release wait fell from 0.28 to 0.11, from fewer gated diff --git a/docs/ci/ci-cleanup-log.md b/docs/ci/ci-cleanup-log.md index ef9f3fac..06cfb6ca 100644 --- a/docs/ci/ci-cleanup-log.md +++ b/docs/ci/ci-cleanup-log.md @@ -20,7 +20,7 @@ them wrong. | 2026-10-06 | `DirectGLES.HandleRecycle.Legacy.*`, `DirectVulkan.HandleRecycle.Legacy.*`, `DirectVulkan.HandleRecycle.AbaControl.*` | Test / integration-gpu (`integration-monolith-control`) | they ran `MOBILEGL_PIPE_PUSH=0`, the pre-handle arm, which P13 W3b removed with `MOBILEGL_PIPE_LEGACY_MEMOS` (ID-P13-3) | `HandleRecycle.Handles.*` and `DirectVulkan.HandleRecycle.AbaControlHandles.*` (the ABA control against the handle arm that ships) stay | | 2026-10-06 | `DirectGLES.ResourceSubsystemControl.Off.*`, `DirectGLES.ResourceSubsystemOff.*`, `DirectGLES.ObjectSubsystemControl.{Off,Refused,RefusedTexture}.*` | Test / integration-gpu | they cleared subsystem bits (masks 0x7f / 0x1ff / 0x9ff / 0x5ff) to run legacy arms; since W3b bits 0-13 are fixed on (ID-P13-3) | one named-refusal control per lane, `DirectGLES.SubsystemMaskRefusal.`: the same scenario and mask must go red with `Fatal{PipeSubsystemsFixedOn}` naming that mask (`Harness/RefusedMaskControl.cmake`); the `On` lanes now run 0x3fff | | 2026-10-06 | `SanityTest`: `DirectGLESSlotTable.{AnArmlessKnobCombinationStopsInsteadOfSkippingTheLane, TheArmlessCasesLeaveTheLogPathAndTheConfigAsTheyFoundThem, EglBringUpUnderTheArmlessKnobPairReturnsInsteadOfStopping}` | Test / unit | they pinned the `MOBILEGL_PIPE_LEGACY_MEMOS=0` + cleared-bit knob pair; the knob is gone and the mask is refused at startup | the SubsystemMaskRefusal controls above | -| 2026-10-06 | `SanityTest`: `DirectGLESTextureSync.AnAttachmentOnlyTexturesParametersReachTheDriverWithNoSamplerView` | Test / unit | **not a behaviour gap.** At 0x3fff the parameter push is record-addressed (`SyncTextureParamsToBackend` reads the texture's applier record; nothing in it consults a sampler view), but the unit lane cannot create that record (`NoP4aConsumer`, as above), so the probe's handle half never had a record to read; its legacy half pinned the pre-handle push that W3b removed | `TextureParamsWithoutASamplerViewScenario` (G9): its four cases take a WHITE-BOX reading of the driver-side parameters before any sample (`TakeTheWhiteBoxReadingBeforeAnySample`, ID-19), at the shipping mask on every lane - the same property, observed where records exist | +| 2026-10-06 | `SanityTest`: `DirectGLESTextureSync.AnAttachmentOnlyTexturesParametersReachTheDriverWithNoSamplerView` | Test / unit | **not a behavior gap.** At 0x3fff the parameter push is record-addressed (`SyncTextureParamsToBackend` reads the texture's applier record; nothing in it consults a sampler view), but the unit lane cannot create that record (`NoP4aConsumer`, as above), so the probe's handle half never had a record to read; its legacy half pinned the pre-handle push that W3b removed | `TextureParamsWithoutASamplerViewScenario` (G9): its four cases take a WHITE-BOX reading of the driver-side parameters before any sample (`TakeTheWhiteBoxReadingBeforeAnySample`, ID-19), at the shipping mask on every lane - the same property, observed where records exist | | 2026-10-06 | unit `RenderStateSpans.{ResidualTripWireIsSilentUntilTheApplierOwnsTheBytes, ResidualTripWireHoldsAcrossAVerbClassThatDoesNotPublishTheBlock, ResidualTripWireFiresNamingTheCapability}` and PeerLatchTest's `SetResidualValueStateBlobSize` row | Test / unit | P13 W3c deleted ResidualValueBlock and its applier trip wire (op 46 is a retired, declined row) | integration-verify's new `Negative control A2 (corrupted capability)`: the verify comparator must go red on a corrupted `IsCapabilityEnabled`; `PipeWireCodecTest.ResidualValueBlockCrossesAsItsOwnBlob` now pins that op 46 is declined; `TrackerTest...AClipDistanceEnableReArmsTheResidualBlock` now asserts the capability reaches the applier's block | | 2026-10-06 | unit `DirectGLESBufferDrawProbe.ALiveHostMapKeepsTheHandleArmProbeDirtyBetweenTwoDraws` | Test / unit | P13 W6: it pinned the frontend arm's draw-time `SyncPersistentMappedRange` keeping a live host map's probe dirty; that per-draw hook is deleted - the record arm publishes a live map's span at push time (`PersistentMapTracker`) | `PersistentCoherentMapScenario` and `SplitBufferTest`'s persistent-map push / live-host-writes cases, on every arm | | 2026-10-06 | unit `DirectGLESSanity.{BindsAMultisampleTextureDespiteTheDefaultMipmapFilter, BindingZeroClearsPreviousNativeTextureBinding}` | Test / unit | P13 W6: GL 4.6 8.17 / 8.17.1 rules, but asserted through the deleted frontend arm's unit walk (`BindCurrentTextures` over frontend binding slots); every library walks the units by handle now | moved, not dropped: `TextureUnitSamplingScenario` (integration-gpu on both backends plus the split arms) asserts both rules on a real context | @@ -70,7 +70,7 @@ them wrong. ### `minecraft-1.17-main-menu-854` (Test retrace / retrace-split / retrace-verify, APK retrace), 2026-10-06 - **Symptom**: every lane, both backends, SSIM 0.0186 against the golden; the frame is Minecraft's - red loading-screen colour. Local repro on WSL llvmpipe: same SSIM, monolith and inproc. + red loading-screen color. Local repro on WSL llvmpipe: same SSIM, monolith and inproc. - **Root cause**: the trace was captured on an implementation that gave shaders and programs **overlapping names** (shader 1 and program 1 live at once, likewise shader 5 / program 5, calls 159-209). GL 4.6 core and ES 3.2 §7.1 put shader and program objects in one shared name @@ -100,7 +100,7 @@ them wrong. ### `SanityTest` `DirectGLESTextureSync.UnitMemoRefusesToDriveATwinFromAnotherTexture`, 2026-10-06 (removed in W3b, then RESTORED) - **First call (wrong)**: retired with the P2-mask probes as "its arm is gone". The orchestrator's - review asked whether its failure at the shipping mask was a behaviour gap. + review asked whether its failure at the shipping mask was a behavior gap. - **Finding**: the code it pins is LIVE. The monolith arm (DISAGG builds under `MOBILEGL_TRANSPORT=monolith`, and the FCL build) still walks the frontend units with the borrowed-slot work list and its `PairingsIntact` check (`UnitTexturesByHandle()` is false on diff --git a/scripts/bake_internal_shaders.py b/scripts/bake_internal_shaders.py index 77474037..01d453ac 100644 --- a/scripts/bake_internal_shaders.py +++ b/scripts/bake_internal_shaders.py @@ -24,7 +24,7 @@ A gate whose baker is a different program from the gate has the same failure one day the CLI's defaults and the library's diverge, the gate reds on a header nobody can regenerate, and the fix is to edit the words by hand. -FORMATTING IS PRESERVED PER HEADER, not normalised: the headers in the tree disagree about +FORMATTING IS PRESERVED PER HEADER, not normalized: the headers in the tree disagree about words per line and about the `u` suffix, and reformatting one of them would bury a one-word change in a whole-file diff. The style is read back out of the array being replaced. diff --git a/scripts/check_include_closure.py b/scripts/check_include_closure.py index 6e544481..e68818e5 100644 --- a/scripts/check_include_closure.py +++ b/scripts/check_include_closure.py @@ -224,7 +224,7 @@ def repo_relative(path, cwd): """normpath the -H spelling, then express it repo-relative with forward slashes. Today's transcripts contain e.g. TextureState/../SamplerState/SamplerObject.h, which - only matches a forbidden prefix after normalisation. Anything outside the repo (the + only matches a forbidden prefix after normalization. Anything outside the repo (the toolchain's own headers, /usr/include) is not our business and returns None. """ absolute = os.path.normpath(os.path.join(cwd, path)) @@ -498,7 +498,7 @@ Multiple include guards may be useful for: def self_test_parser(): - """Check 4: the trailer paragraph is discarded and a `../` spelling normalises.""" + """Check 4: the trailer paragraph is discarded and a `../` spelling normalizes.""" problems = [] entries = parse_h_output(PARSER_CANNED_GXX, REPO_ROOT) if len(entries) != 3: @@ -508,14 +508,14 @@ def self_test_parser(): problems.append("depths misparsed: {}".format(depths)) normalised = entries[-1][1] if entries else None if normalised != "MobileGL/MG_State/GLState/SamplerState/SamplerObject.h": - problems.append("`../` spelling did not normalise: {}".format(normalised)) + problems.append("`../` spelling did not normalize: {}".format(normalised)) elif not find_violations(entries, PROBES[0]["Forbidden"], []): - problems.append("normalised path did not match the value-header forbidden list") + problems.append("normalized path did not match the value-header forbidden list") if problems: for problem in problems: say(" self-test parser: " + problem) return False - say(" self-test parser: trailer discarded, `../` normalised and matched") + say(" self-test parser: trailer discarded, `../` normalized and matched") return True diff --git a/scripts/ci/espryt_memo_purity.py b/scripts/ci/espryt_memo_purity.py index a52c5a81..49943b04 100644 --- a/scripts/ci/espryt_memo_purity.py +++ b/scripts/ci/espryt_memo_purity.py @@ -20,7 +20,7 @@ exemptions; the first is gone from the tree, and the second is compiled into the embeds (the push monolith without MG_Remote), so it is shipped code and gets the same rule. The rule is now "no frontend-pointer KEY in any named memo family, in any build", and nothing else; the one allow-list entry below is a named, dated carve-out. -It does not evaluate the preprocessor - it recognises the conditional spellings the +It does not evaluate the preprocessor - it recognizes the conditional spellings the tree actually uses - and it does not look at DirectVulkan, whose own key inventory is P7 wave 2's. @@ -107,7 +107,7 @@ def legacy_lines(code: str) -> set[int]: def _retired_legacy_lines(code: str) -> set[int]: """The pre-W3b exemption, kept only for the self-test's record of what changed. - NOT a preprocessor. It recognises `#if MOBILEGL_PIPE_LEGACY_MEMOS`, + NOT a preprocessor. It recognizes `#if MOBILEGL_PIPE_LEGACY_MEMOS`, `#if !MOBILEGL_BUILD_DISAGGREGATED`, and the `#else` of `#if MOBILEGL_BUILD_DISAGGREGATED` - which is every spelling these two files use - and treats every other conditional as transparent.""" diff --git a/scripts/ci/fatal_census.py b/scripts/ci/fatal_census.py index 06391d48..775a8186 100644 --- a/scripts/ci/fatal_census.py +++ b/scripts/ci/fatal_census.py @@ -41,7 +41,7 @@ and integration harnesses drive the library rather than being it. THE SITES OF THE WIDENED PERIMETER, TRIAGED. The widening found 83; the same package routed five of them through Session::Fail and added one funnel of its own, so the floor the baseline records is 79 over 20 files. The triage is the argument for why the gate can be green with -seventy-nine deaths inside it. The ENFORCEABLE artefact is the baseline's per-file map - this +seventy-nine deaths inside it. The ENFORCEABLE artifact is the baseline's per-file map - this prose is why that map reads the way it does. (i) INSIDE A SANCTIONED FUNNEL - 5 sites, and the only ones allowed to carry no marker. The diff --git a/scripts/ci/junit_tally.py b/scripts/ci/junit_tally.py index 9a7484b3..5393126d 100755 --- a/scripts/ci/junit_tally.py +++ b/scripts/ci/junit_tally.py @@ -73,7 +73,7 @@ def _list_property(test, name): def tcp_lock_violations(document): """Entries of a ctest --show-only=json-v1 document that reach the loopback TCP supervisor - - FIXTURES_REQUIRED names mobilegl-tcp, or the entry is labelled exactly integration-tcp - and do + FIXTURES_REQUIRED names mobilegl-tcp, or the entry is labeled exactly integration-tcp - and do not hold RESOURCE_LOCK mobilegl-tcp. Sorted names; empty when the registration is sound.""" bad = [] for test in document.get('tests', []): @@ -121,7 +121,7 @@ def require_entries_passed(path, names): `TcpLane.SupervisorProtocolControls` is registered with SKIP_RETURN_CODE 77 because the script it runs needs flatc, which is deliberately not in the build graph. That is the right - behaviour for a developer who has not built one; it is the wrong behaviour for CI, where the + behavior for a developer who has not built one; it is the wrong behavior for CI, where the lane's whole job is to run the supervisor's protocol controls and "skipped" is indistinguishable from the three commits the entry did not exist. The workflow builds flatc and then names the entry here, so a CI run in which the tool went missing reds by name diff --git a/scripts/ci/ph_latch_sites.py b/scripts/ci/ph_latch_sites.py index eeb3acd3..b39aa00b 100644 --- a/scripts/ci/ph_latch_sites.py +++ b/scripts/ci/ph_latch_sites.py @@ -53,7 +53,7 @@ FILES = { } # (file, a substring of the site's line) -> why no peer byte reaches it. The site is converted -# anyway - it is on the decode path and returns like its neighbours - and the reason names the +# anyway - it is on the decode path and returns like its neighbors - and the reason names the # earlier check that refuses the same bytes first. UNREACHABLE = [ ("PipeWireCodec.cpp", '"segment-resolve"', diff --git a/scripts/ci/protocol_revision_pin.py b/scripts/ci/protocol_revision_pin.py index 6e19805c..2b85c060 100644 --- a/scripts/ci/protocol_revision_pin.py +++ b/scripts/ci/protocol_revision_pin.py @@ -18,7 +18,7 @@ surface as a silently absent field - the exact failure the revision was added to This script pins the two together. protocol_revision_pins.json beside it is a table {revision: sha256(protocol.fbs)} of the schema each revision was minted for. The check reads the -header's current revision, hashes protocol.fbs (line endings normalised, so a CRLF checkout hashes +header's current revision, hashes protocol.fbs (line endings normalized, so a CRLF checkout hashes the same bytes as an LF one) and refuses when the current revision has no row or its row is not the file's digest. Both directions are covered: a schema edit that forgot the bump is red (stale row), and a bump that forgot the table is red (no row), so the table cannot fall behind the header. diff --git a/scripts/ci/spawn_lane_parity.py b/scripts/ci/spawn_lane_parity.py index f04f9ac8..43de49dc 100644 --- a/scripts/ci/spawn_lane_parity.py +++ b/scripts/ci/spawn_lane_parity.py @@ -25,7 +25,7 @@ runs", not "runs inproc"), and that arm's scenario is monolith-only by construct have a spawn counterpart, so it is named as an exception rather than allowed to widen the tolerance for everything else. -P7 PACKAGE L ADDS THE SAME QUESTION FOR MAGMA, IN TWO TIERS, AND THE NORMALISATION IS +P7 PACKAGE L ADDS THE SAME QUESTION FOR MAGMA, IN TWO TIERS, AND THE NORMALIZATION IS DIFFERENT ON PURPOSE. The Espryt half above strips the sub-lane tails `F1.` and `Ct.` because they name neither the case nor the arm. The Magma half must NOT: `RunAhead.Credit1.` and `RunAhead.Credit3.` are two entries of the same case, differing in the credit the lane pins, and diff --git a/scripts/ci/split_coverage.py b/scripts/ci/split_coverage.py index 6e191d3d..92b55401 100755 --- a/scripts/ci/split_coverage.py +++ b/scripts/ci/split_coverage.py @@ -19,7 +19,7 @@ asked about - and nothing about a green split lane says so. This asserts, per ba after the arm and tail segments come off both sides: an entry name is `.[.][.] .`, and only the last two segments (the gtest name) are compared. `Split.F1.`, `Spawn.ForcedDs.`, `Tcp.MultiDrawTierBaseVertex.` and the monolith's -`ForcedDepthStencilEmulation.` all normalise away. +`ForcedDepthStencilEmulation.` all normalize away. WHAT COUNTS AS A SPLIT CASE differs by backend, on purpose: * DirectGLES - an entry with an arm segment (Split/Spawn/Tcp/TcpDevice) that carries a GATED @@ -33,7 +33,7 @@ WHAT COUNTS AS A SPLIT CASE differs by backend, on purpose: WHAT COUNTS AS A MONOLITH CASE: an entry with no arm segment carrying `integration-gpu` - the label the monolith registrations and the monolith-control mechanism entries share. That puts -`DirectGLES.PushMonolithArm.` (labelled integration-split, but no arm) on the monolith side, +`DirectGLES.PushMonolithArm.` (labeled integration-split, but no arm) on the monolith side, where it belongs, and leaves build-verify's `DirectGLES.VerifySplit.` (no integration-gpu) out of both sides. @@ -254,7 +254,7 @@ def self_test(): if got != rc or any(n not in text for n in needles) or any(n in text for n in absent): failures.append(f"{label}: rc {got} (want {rc}); output:\n{text}") - expect("tails normalise on both sides", _doc(*BASE), "", 0, + expect("tails normalize on both sides", _doc(*BASE), "", 0, "DirectGLES: monolith 3, on a gated split arm 3", "missing 0") expect("a monolith case on no arm reds BY NAME", _doc(*BASE, _entry("DirectGLES.CScenario.Five", "integration-gpu")), "", 1, diff --git a/scripts/ci/tcp_lane_tools_test.py b/scripts/ci/tcp_lane_tools_test.py index 7e43e6af..d77e05a6 100644 --- a/scripts/ci/tcp_lane_tools_test.py +++ b/scripts/ci/tcp_lane_tools_test.py @@ -189,7 +189,7 @@ class Accounting(unittest.TestCase): `ctest -L integration-gpu -j 4` that entry and another Tcp case killed each other. The stub mirrors the real json-v1 shapes: the fixture's own setup entry, a sound Tcp case, the violator as it was registered, a Magma tcp entry that reaches the fixture - under another label, a labelled control with no fixture, and the device lane, whose + under another label, a labeled control with no fixture, and the device lane, whose lock is its own.""" tally = module('junit_tally') parity = module('spawn_lane_parity') diff --git a/scripts/gen_pipe.py b/scripts/gen_pipe.py index 3055bb51..7bc2c65a 100644 --- a/scripts/gen_pipe.py +++ b/scripts/gen_pipe.py @@ -10,7 +10,7 @@ Reads the four hand-maintained sources of truth - MobileGL/MG_Pipe/PipeCalls.def the call catalogue + MobileGL/MG_Pipe/PipeCalls.def the call catalog MobileGL/MG_Pipe/PipeFields.def per-payload field lists for the verify comparator MobileGL/MG_Pipe/Coverage.def accessor -> call mapping for the read inventory, and the sticky-field list @@ -23,13 +23,13 @@ plus the vendored copy of the backend read inventory and writes MobileGL/MG_Pipe/generated/*.inc. The outputs are COMMITTED; CI regenerates them and fails on a diff, which is what keeps the seven generators from drifting apart -from the catalogue (they all consume the same .def). +from the catalog (they all consume the same .def). python3 scripts/gen_pipe.py # write the generated files, print the summary python3 scripts/gen_pipe.py --check # fail if regenerating would change anything python3 scripts/gen_pipe.py --self-test # the negative controls: each gate below must trip -Both modes refuse a catalogue whose call payload has no field list in PipeFields.def: a +Both modes refuse a catalog whose call payload has no field list in PipeFields.def: a payload the G4 comparator cannot see is a payload MOBILEGL_PIPE_VERIFY is blind to. Both also refuse a field list that does not name every data member of its struct (or names one that is not a member), and a backend accessor read through gPipeInputs-> / pGLContext-> that @@ -573,7 +573,7 @@ def parse_wait_classes(): this list is what the generated kMGPipeWaitClasses[] table spells into C++, and a copy here would go stale in exactly the case that matters. kWaitClassCount is the terminator and is NOT a class a row may carry - a row that named it would generate a table entry the - lookup uses to mean 'this opcode never came from the catalogue'.""" + lookup uses to mean 'this opcode never came from the catalog'.""" text = read(os.path.join(PIPE_DIR, "MGPipe.h")) body = WAIT_ENUM_RE.search(text) if not body: @@ -597,7 +597,7 @@ def check_wait_classes_are_known(calls): compile error in one consumer. 1. The token must be an MGPipeWaitClass enumerator, and never the kWaitClassCount - terminator, which the generated lookup uses for "not from this catalogue". + terminator, which the generated lookup uses for "not from this catalog". 2. kReplySlot and kWaitReply must agree, BOTH WAYS. A reply-slot row that did not wait would be a waiter that hangs - the client would run on and read a slot nobody had posted into yet; a waiting row with no slot would block on an answer nobody posts. @@ -690,7 +690,7 @@ def banner(name, title, sources): def gen_wire_layout(calls, payloads): """Compiler-evaluated wire layout, including same-width member reorders.""" - out = [banner("PipeWireLayout.inc", "P6.5: wire layout and ordered catalogue.", + out = [banner("PipeWireLayout.inc", "P6.5: wire layout and ordered catalog.", "PipeFields.def and PipeCalls.def")] out += ["struct WireLayoutMember { const char* Name; Uint64 Offset; Uint64 Size; };", "inline constexpr WireLayoutMember kMGPipeWireLayoutMembers[] = {"] @@ -735,12 +735,12 @@ def gen_tables(calls): out.append("// A table that is not exactly its call count of function pointers has grown a") out.append("// member that no generator knows about.") out.append("static_assert(sizeof(MGPipeScreen) == kMGPipeScreenCallCount * sizeof(void (*)()),") - out.append(" \"MGPipeScreen is not exactly its catalogue's function pointers\");") + out.append(" \"MGPipeScreen is not exactly its catalog's function pointers\");") out.append("static_assert(sizeof(MGPipeContext) == kMGPipeContextCallCount * sizeof(void (*)()),") - out.append(" \"MGPipeContext is not exactly its catalogue's function pointers\");") + out.append(" \"MGPipeContext is not exactly its catalog's function pointers\");") out.append("static_assert(kMGPipeScreenCallCount + kMGPipeContextCallCount == kMGPipeCallCount);") out.append("static_assert(kMGPipeCallCount == MGP_CALL_LIST_DOCUMENTED_COUNT,") - out.append(" \"the catalogue and its documented count disagree\");") + out.append(" \"the catalog and its documented count disagree\");") return "\n".join(out) + "\n" @@ -833,8 +833,8 @@ enum class MGPWireOp : Uint16 { // GetCaps and CreateSamplerState came to carry an MGPBlobRef member with no kHasBlob on // their line at all - nothing compared the two, because nothing had both in one place. // -// Index 0 is MGPWireOp::kInvalid and is kNone: the catalogue is 1-based, and an encoder -// that reads flags for an opcode it never got from the catalogue must see the empty set +// Index 0 is MGPWireOp::kInvalid and is kNone: the catalog is 1-based, and an encoder +// that reads flags for an opcode it never got from the catalog must see the empty set // rather than another call's flags. // // kHasBlob here means EXACTLY "the payload owns an MGPBlobRef member". Three calls carry @@ -853,7 +853,7 @@ enum class MGPWireOp : Uint16 { out.append(" \"the flags table and the opcode space disagree\");") out.append(""" // The only supported read of the table. Out-of-range is kNone rather than undefined -// behaviour, because the one caller that can pass a bad opcode is a decoder holding bytes +// behavior, because the one caller that can pass a bad opcode is a decoder holding bytes // off a stream, and it must reach its own Fatal{ProtocolCorruption} rather than read past // the array on the way there. inline constexpr Uint32 MGPipeCallFlagsFor(MGPWireOp op) { @@ -862,7 +862,7 @@ inline constexpr Uint32 MGPipeCallFlagsFor(MGPWireOp op) { : static_cast(kNone); } -// The catalogue class of every opcode, indexed the same way; index 0 is kCallClassCount, +// The catalog class of every opcode, indexed the same way; index 0 is kCallClassCount, // never a real class, for the flags table's reason. inline constexpr Uint8 kMGPipeCallClasses[static_cast(MGPWireOp::kOpCount)] = { /* 0 */ static_cast(kCallClassCount), @@ -883,7 +883,7 @@ inline constexpr MGPipeCallClass MGPipeCallClassFor(MGPWireOp op) { // P5e (2.2): THE WAIT CLASS OF EVERY OPCODE, indexed the same way. // Index 0 is kWaitClassCount - never a real class - for the flags table's reason: the one -// caller that can pass an opcode this catalogue never produced is a decoder holding bytes off +// caller that can pass an opcode this catalog never produced is a decoder holding bytes off // a stream, and it must reach its own Fatal{ProtocolCorruption} rather than a wait decision. // // This is the STATIC HALF of MGPipeBarriered(op, payload, applierState), the predicate the emit @@ -908,7 +908,7 @@ inline constexpr MGPipeWaitClass MGPipeWaitClassFor(MGPWireOp op) { } // THE COLUMN'S OWN INVARIANT, stated in C++ as well as in the generator: a reply-slot row -// waits for its reply and a waiting row owns a slot. gen_pipe.py refuses a catalogue where the +// waits for its reply and a waiting row owns a slot. gen_pipe.py refuses a catalog where the // two disagree, and this is the same statement where a reader of the generated table will look // for it - a kReplySlot row that did not wait would run on and read a slot nobody had posted // into, and a kWaitReply row with no slot would block on an answer nobody posts. @@ -923,7 +923,7 @@ static_assert(MGPipeWaitClassFor(MGPWireOp::ApplierReset) == kWaitApplied, static_assert(MGPipeWaitClassFor(MGPWireOp::ReadPixels) == kWaitReply, "a readback's answer is not derivable (R-5)"); -// Spot checks the generator states about its own output, so that a catalogue edit that +// Spot checks the generator states about its own output, so that a catalog edit that // silently drops a flag is a build break here and not a wrong decode six packages away. static_assert(MGPipeCallFlagsFor(MGPWireOp::kInvalid) == static_cast(kNone), "opcode 0 is not a call and carries no flags"); @@ -1011,9 +1011,9 @@ inline MGPipeWireRecordApplyFn gMGPipeWireRecordApply = nullptr; // record's own count fields and require it to EQUAL MGPWireRecHeader::Size - belongs to the // decoder, which has the payload (MG_Remote/Wire's MGPipeWireRecordLayout, P5 w1). // -// The switch and the opcode enum come from the same list, so a call added to the catalogue +// The switch and the opcode enum come from the same list, so a call added to the catalog // cannot be forgotten here; the default arm is for the opcode that never came from this -// catalogue at all - a byte off a corrupt stream - and it is fatal for the same reason the +// catalog at all - a byte off a corrupt stream - and it is fatal for the same reason the // bounds check is. // // With no decoder installed - every monolith build, and a split build before @@ -1661,7 +1661,7 @@ def self_test(accessors): # The positive control: the canned struct's exact list passes, and the parser sees the # padding member as padding and the function as not a member. check_field_lists_cover_struct_members({"Canned": ["A", "B", "C"]}, ["Canned"], [canned_struct]) - # ... and the real catalogue's real flags and wait classes pass the same gates. + # ... and the real catalog's real flags and wait classes pass the same gates. check_call_flags_are_known(calls_for_control) check_wait_classes_are_known(calls_for_control) if trips == 0: diff --git a/scripts/gen_pipe_dirty_surface.py b/scripts/gen_pipe_dirty_surface.py index 1099dec7..336077b3 100644 --- a/scripts/gen_pipe_dirty_surface.py +++ b/scripts/gen_pipe_dirty_surface.py @@ -343,7 +343,7 @@ def render_state_publishers(): # not read. What it models is written down here, and what it does not model taints the # function it is in, which turns every answer depending on that function into UNDECIDED: # -# modelled ++m_x / m_x = / m_x op= (a whole-member write: MEM:m_x, FIELD:m_x.*); a write +# modeled ++m_x / m_x = / m_x op= (a whole-member write: MEM:m_x, FIELD:m_x.*); a write # through a member-rooted lvalue (m_x.f, m_x[i].f, m_x->f, nested), which records # MEM:m_x and FIELD:m_x.f - the first field below the member, deeper paths # collapse to it, because that is the granularity the shutter reads at; a @@ -356,7 +356,7 @@ def render_state_publishers(): # memcpy/memset/memmove/swap whose destination is one, all credited as a whole # write of that lvalue - a read-only call is over-credited, which only WIDENS the # writer side; a write to a value local, a by-value parameter or an aggregate -# initialiser's `.f = v`, which touch no member; a write through a const alias +# initializer's `.f = v`, which touch no member; a write through a const alias # with `.` or through a const raw pointer, which the language forbids - but `->` # through a const REFERENCE may be a smart pointer's and is NOT taken as # read-only; MGP_NOTE_AGGREGATE; a call to any function whose body is under the @@ -417,7 +417,7 @@ AGGREGATE_CASE_RE = re.compile(r"case\s+MGPipeAggregate::(\w+)\s*:\s*([^;]*);") # is then `!`, `<` or `>` and no alternative here begins with one except <<= / >>=. ASSIGN = r"(?:\+\+|--|\+=|-=|\*=|/=|%=|&=|\|=|\^=|<<=|>>=|=(?!=))" # A write to the member itself: ++m_x, m_x = v, m_x += v. Used by the OUTSIDE scan only; the -# analysed bodies go through extract_writes below. +# analyzed bodies go through extract_writes below. MEMBER_WRITE_RE = re.compile(r"\+\+\s*(m_\w+)|\b(m_\w+)\s*%s" % ASSIGN) # A write THROUGH a member: m_x.f = v, m_x[i].f = v, m_x->f = v, and nested. Outside scan only. MEMBER_ROOTED_WRITE_RE = re.compile( @@ -451,8 +451,8 @@ READ_ONLY_METHODS = frozenset(("size", "empty", "begin", "end", "cbegin", "cend" # memcpy(&dst, ...), memset(&dst, ...), memmove(&dst, ...), swap(a, b): whole writes. BULK_RE = re.compile(r"\b(?:std\s*::\s*)?(memcpy|memmove|memset|swap)\s*\(") # A local declaration: [qualifiers] Type[<...>][::More] [const] [& | && | *] name, then the -# initialiser's opener. A `&`/`*` mark (or an initialiser that takes an address) makes the -# local an ALIAS whose initialiser must resolve to a member-rooted lvalue; anything else is +# initializer's opener. A `&`/`*` mark (or an initializer that takes an address) makes the +# local an ALIAS whose initializer must resolve to a member-rooted lvalue; anything else is # a value local, which cannot alias a member - unless the body later writes through it with # `->` or `*`, in which case it is a pointer or an iterator and is treated as an alias. A # pointer alias is REBOUND by `p = expr;` (every binding counts); a reference alias is @@ -494,7 +494,7 @@ ASSIGN_OP_RE = re.compile(r"(\+\+|--|<<=|>>=|[-+*/%&|^]=|(?\[\-+*/%&|^])= # answered. MACRO_DIRECTIVE_RE = re.compile( r"^[ \t]*#[ \t]*(define|undef)[ \t]+(\w+)(\([^()\n]*\))?((?:\\\n|[^\n])*)", re.M) -# MGP_NOTE_AGGREGATE is modelled directly (its hop is read out of MGPipeNoteAggregate's own +# MGP_NOTE_AGGREGATE is modeled directly (its hop is read out of MGPipeNoteAggregate's own # switch), so expanding it would delete the very token AGGREGATE_RE looks for. NEVER_EXPAND = frozenset(("MGP_NOTE_AGGREGATE", "MGP_NOTE_MUTATION")) MACRO_BODY_LIMIT = 4000 @@ -856,7 +856,7 @@ def extract_writes(body, params_text, site): % (site, what, root)) def designated(text, root_at): - """`{.f = v, .g = w}`: an aggregate initialiser, not a write to a field named f.""" + """`{.f = v, .g = w}`: an aggregate initializer, not a write to a field named f.""" before = text[:root_at].rstrip() if not before.endswith("."): return False @@ -934,7 +934,7 @@ def extract_writes(body, params_text, site): def state_bodies(): """({function name: [body text]}, {function name: [parameter text]}, - {function name: {taint reason}}, [analysed paths]) over MG_State/GLState and + {function name: {taint reason}}, [analyzed paths]) over MG_State/GLState and MG_Impl/Pipe, macros expanded first.""" paths = [] for root in STATE_ROOTS: @@ -962,15 +962,15 @@ def state_bodies(): def writers_outside(analysed): - """{MEM token: a file OUTSIDE the analysed roots that writes it}. + """{MEM token: a file OUTSIDE the analyzed roots that writes it}. The absence claim is only as good as the set of writers the analysis reads. Every .h/.cpp - under MobileGL/ that is not one of the analysed files is scanned with the direct write + under MobileGL/ that is not one of the analyzed files is scanned with the direct write patterns, and a shutter member that turns up here is undecided rather than answered. A file that DECLARES a member of that name is writing its own, not the frontend's - the backend's PipeInputs mirrors half of GLState's member names - so its writes do not count. - That is the one judgement here, and it is the conservative way round only for names the + That is the one judgment here, and it is the conservative way round only for names the two sides share; a genuine outside writer of a frontend member does not declare it. This scan is textual and file-wide: it sees a direct member write and a member-rooted @@ -1375,7 +1375,7 @@ def derive_bit_answers(mapping, bits, movers, moved, outside=None): unread = sorted(set(outside[token] for token in shutter if token in outside)) if unread: out[(mutator, bit)] = (UNDECIDED, "that shutter's members are written outside " - "the analysed roots too, e.g. %s, so 'it writes " + "the analyzed roots too, e.g. %s, so 'it writes " "nothing that shutter reads' is not a fact this " "script has" % unread[0]) continue @@ -1702,8 +1702,8 @@ def self_test(scanned, bits, publishers, movers, moved, outside=None, undecided_ hidden[token] = "MobileGL/MG_Backend/a-file-this-analysis-never-reads.cpp" verdicts = derive_bit_answers(with_wrong_bit, bits, movers, moved, hidden) verdict, detail = verdicts.get(("SetCurrentVertexAttributeInt", "NEW_PIXEL_PACK"), ("", "")) - tripped(verdict == UNDECIDED and "outside the analysed roots" in detail, - "10 (a shutter member written outside the analysed roots)") + tripped(verdict == UNDECIDED and "outside the analyzed roots" in detail, + "10 (a shutter member written outside the analyzed roots)") # 11-14. THE WRITE ANALYSIS ITSELF, on synthetic bodies through the real extractor. The # review's false verdict was "SetBlendEquation writes nothing NEW_PATCH_STATE's diff --git a/scripts/gen_pipe_field_ownership.py b/scripts/gen_pipe_field_ownership.py index d3a27fc5..dcb4869b 100644 --- a/scripts/gen_pipe_field_ownership.py +++ b/scripts/gen_pipe_field_ownership.py @@ -197,7 +197,7 @@ def parse_ownership(text=None): def parse_ops_and_verbs(calls_text=None, fill_points_text=None): """The two name spaces the stamp map joins, read from the files that define them: the - catalogue's calls (PipeCalls.def, which IS the MGPWireOp enum, with each call's KIND) and + catalog's calls (PipeCalls.def, which IS the MGPWireOp enum, with each call's KIND) and the verb set (FillPoints.def, which IS MG_Backend::GLFunctionsTable's member list).""" calls_text = read(PIPE_CALLS) if calls_text is None else calls_text fill_points_text = read(FILL_POINTS) if fill_points_text is None else fill_points_text @@ -213,7 +213,7 @@ def parse_ops_and_verbs(calls_text=None, fill_points_text=None): def array_block(text, declaration): - """The braced initialiser of a generated `... = {` table, comments KEPT. + """The braced initializer of a generated `... = {` table, comments KEPT. The generated tables carry the row's name in a trailing comment (`// DrawArrays`) and in a leading one (`/* 58 ReadPixels */`), and those comments are the only place the row's NAME @@ -236,7 +236,7 @@ def array_block(text, declaration): if depth == 0: return text[open_at + 1:i] i += 1 - sys.exit("gen_pipe_field_ownership: %r never closes its initialiser" % declaration) + sys.exit("gen_pipe_field_ownership: %r never closes its initializer" % declaration) WAIT_ROW_RE = re.compile(r"/\*\s*\d+\s+(\w+)\s*\*/\s*static_cast\(\s*(k\w+)\s*\)") @@ -386,7 +386,7 @@ def build_admitted(accessors, ownership, phase, verbs, verb_ops, waits, verb_cla def verb_shaped_calls(calls, verbs): """The calls that MUST have a stamp row or an exemption, by two derived tests: the - catalogue's own kind (kCtxVerb) and a name that is also a verb's. Neither can see a call + catalog's own kind (kCtxVerb) and a name that is also a verb's. Neither can see a call that is a verb boundary, is not kCtxVerb and is renamed - FieldOwnership.def names the one such call in the tree and says the phase that emits it writes its row.""" verbSet = set(verbs) @@ -946,7 +946,7 @@ def self_test(): # alone and control 12 would pass for the wrong reason. Renaming the kind is the cheapest # way to prove the kind is actually being read. kindless = read(PIPE_CALLS).replace("kCtxVerb", "kCtxVerbb") - controls.append(("the catalogue's kCtxVerb kind renamed away", + controls.append(("the catalog's kCtxVerb kind renamed away", "is exempted from the stamp map but is not verb-shaped", lambda: run(calls_text=kindless))) diff --git a/scripts/p3a_untouched_regions.sh b/scripts/p3a_untouched_regions.sh index 71107f30..6acc0fb0 100644 --- a/scripts/p3a_untouched_regions.sh +++ b/scripts/p3a_untouched_regions.sh @@ -7,7 +7,7 @@ # SPDX-License-Identifier: LGPL-3.0-only # End of Source File Header -# G5's gate: "pool 与延迟释放原样搬" is LITERAL - ELEVEN functions in +# G5's gate: "the pool and the deferred release are moved as they are" is LITERAL - ELEVEN functions in # MobileGL/MG_Backend/DirectGLES/Managers.cpp are byte-identical after P3a. # # WHAT G5 CLAIMS, and why a diff of the file cannot say it. ARCHITECTURE.md §9.1 puts the three diff --git a/scripts/p3a_vertex_input_negative_control.sh b/scripts/p3a_vertex_input_negative_control.sh index 1ee6fc7d..bf93cab0 100644 --- a/scripts/p3a_vertex_input_negative_control.sh +++ b/scripts/p3a_vertex_input_negative_control.sh @@ -26,7 +26,7 @@ # four static_asserts in MGPipeValueTypes.h's trip-wire block still hold, the field list in # PipeFields.def still names it and the generated comparator still compares it. What breaks is the # VALUE - the wire record now says "not BGRA" for a GL_BGRA attribute, which is the shape that made -# a swizzled colour array read back with its channels in driver order. It is also the field with +# a swizzled color array read back with its channels in driver order. It is also the field with # the least other coverage: `Size` keeps 4 for GL_BGRA (D-G2), so a dropped IsBgra does not even # change the attribute's size. # @@ -265,7 +265,7 @@ fi case "$VERDICT" in did-not-trip) say "NEGATIVE CONTROL DID NOT TRIP: $TEST_NAME was still green with ${FIELD} no longer copied" - say "into MGPVertexAttribWire. A GL_BGRA attribute travelled as a non-BGRA one and the emission" + say "into MGPVertexAttribWire. A GL_BGRA attribute traveled as a non-BGRA one and the emission" say "comparison did not notice, so G6 is not checking what it claims to check." say "The failing run's output is kept at $LOG_DIR/ctest-after.log" exit 1 diff --git a/scripts/p4a_descriptor_negative_control.sh b/scripts/p4a_descriptor_negative_control.sh index 89c2104d..6f05dd4f 100644 --- a/scripts/p4a_descriptor_negative_control.sh +++ b/scripts/p4a_descriptor_negative_control.sh @@ -40,11 +40,11 @@ # rather than in the code because excluding the hash copy would mean hard-coding another # package's helper name into a regex that deliberately does not know one. # 2. SamplerParameters::borderColorForm stops being copied in MG_Impl/Pipe/SamplerEmit.h. All -# four border-colour VALUES still cross; what is lost is which of the three forms +# four border-color VALUES still cross; what is lost is which of the three forms # (float / int / uint) they are to be read as, and D-F4 is explicit that the form crosses and # that all four values are compared. The failure it models is IntegerBorderColorScenario's: -# an integer border colour read as floats is not an error anywhere, it is just the wrong -# colour at the clamped edge of every sampled texture. +# an integer border color read as floats is not an error anywhere, it is just the wrong +# color at the clamped edge of every sampled texture. # # Each patch is applied by REGEX rather than by an exact line, because both headers belong to OTHER # PACKAGES (C.7: FramebufferEmit.h is package B's, SamplerEmit.h is package C's) and their spelling diff --git a/scripts/p4a_untouched_regions.sh b/scripts/p4a_untouched_regions.sh index 5a106af4..5778b40e 100644 --- a/scripts/p4a_untouched_regions.sh +++ b/scripts/p4a_untouched_regions.sh @@ -42,7 +42,7 @@ # StageBlocksIntoUnpackRing Managers.cpp: the unpack-PBO staging repack. It is what makes the # ring path issue NO glPixelStorei, and the +6 ms/frame Mali cliff # lives on the other side of it -# UnpackRingAvailable Managers.cpp: honours Features.EsprytDisableUnpackRing and +# UnpackRingAvailable Managers.cpp: honors Features.EsprytDisableUnpackRing and # self-heals a stale context generation # UnpackRingAllocate Managers.cpp: on the hot upload route # RecomputeBackendColorSlots Managers.cpp: the attachment permutation - three passes plus the @@ -503,7 +503,7 @@ write_spec() { done } -# Materialise every region source at a git ref into "$2". +# Materialize every region source at a git ref into "$2". checkout_ref() { local ref=$1 dir=$2 source mkdir -p "$dir" || return 2 diff --git a/scripts/symbol_report.py b/scripts/symbol_report.py index 55ebe5d3..0c2a87a1 100644 --- a/scripts/symbol_report.py +++ b/scripts/symbol_report.py @@ -12,7 +12,7 @@ P0.5's acceptance gate says every `nm --defined-only -S` delta has to be explain symbol. The awkward part is that de-nesting a type renames every mangled name that mentions it - `ProgramObject::LinkArtifacts` -> `LinkArtifacts` shows up inside every `std::vector<...>` instantiation too - so a raw nm diff of a pure move looks -catastrophic. `--strip-scope` folds those into a "renamed-only" bucket: same normalised +catastrophic. `--strip-scope` folds those into a "renamed-only" bucket: same normalized demangled name, byte-identical size. What is left over is the report's real content. python3 scripts/symbol_report.py --before old.so --after new.so @@ -195,7 +195,7 @@ def bucket(before, after, only_names, threshold): "before": b["size"], "after": a["size"]}) continue if a["mangled"] != b["mangled"]: - # same normalised name, byte-identical size: the pure-move signature + # same normalized name, byte-identical size: the pure-move signature if wanted(name): renamed.append({"name": name, "delta": 0, "before": b["mangled"][0], "after": a["mangled"][0]}) @@ -302,7 +302,7 @@ def self_test(): if [(r["name"], r["delta"]) for r in resized] != [("MobileGL::Grew()", 0x10)]: problems.append("resized bucket: {}".format([(r["name"], r["delta"]) for r in resized])) # `ProgramObject::LinkArtifacts::Reset` -> `LinkArtifacts::Reset` folds to the same - # normalised name at the same size: renamed-only, not added+removed. + # normalized name at the same size: renamed-only, not added+removed. if [r["name"] for r in renamed] != ["MobileGL::MG_State::GLState::LinkArtifacts::Reset()"]: problems.append("renamed bucket: {}".format([r["name"] for r in renamed])) if unchanged != 2: # ProgramObject::Link() and NoSize() @@ -432,8 +432,8 @@ def main(): say("{} -> {} defined symbols: {} added, {} removed, {} resized, {} renamed".format( before_count, after_count, len(added), len(removed), len(resized), len(renamed))) # The two counts differ by the folding: several mangled symbols can share one - # normalised demangled name (local aliases, `.cold` parts, identical-COMDAT clones). - say("{} -> {} normalised names, {} unchanged (name, size and mangling all identical)".format( + # normalized demangled name (local aliases, `.cold` parts, identical-COMDAT clones). + say("{} -> {} normalized names, {} unchanged (name, size and mangling all identical)".format( len(before), len(after), unchanged)) if only_names: say("listing restricted to names containing: " + ", ".join(only_names)) @@ -468,7 +468,7 @@ def main(): ["symbol", "before", "after", "delta"]) lines += markdown_table("Renamed only (same size)", [(r["name"], r["before"], r["after"]) for r in renamed], - ["normalised symbol", "before mangling", "after mangling"]) + ["normalized symbol", "before mangling", "after mangling"]) report = "\n".join(lines) + "\n" if args.markdown: diff --git a/tools/anland-mobilegl-plasma/SKILL.md b/tools/anland-mobilegl-plasma/SKILL.md index 447fda64..c5e775ae 100644 --- a/tools/anland-mobilegl-plasma/SKILL.md +++ b/tools/anland-mobilegl-plasma/SKILL.md @@ -126,7 +126,7 @@ timeout 25 mgrun offscreen glmark2-es2-wayland -s 1280x720 --run-forever > /tmp/ sleep 8; grep -a "presented through" /tmp/mgl-run.client.log ``` Chrome: `bash scripts/chrome-launch.sh [flags]` (log `/tmp/mgl-chrome-.client.log`, screenshot `ch-.png`; `CHROME_GPU=in-process` puts the GPU back in the browser, which cannot recover from a device loss). -Video: Chrome decodes in hardware. The GPU process's render node has a VA-API driver in the container (`/usr/lib/dri/msm_drm_drv_video.so`, DroidSpaces' V4L2 driver): Chrome allocates its frames with `vaCreateSurfaces` and exports them (`vaExportSurfaceHandle`, one fd, R8 + GR88 layers) - the driver's own buffers, never GBM ones - and imports each as an NV12 (P010 for 10-bit) EGLImage bound to `GL_TEXTURE_EXTERNAL_OES`. MobileGL takes such a FOREIGN YUV dma-buf through its labelled CPU-copy fallback: the server maps it and copies it into a YUV AHardwareBuffer of its own (`AHardwareBuffer_lockPlanes`) at the reader's first use in each frame (any present, publishing flush or native fence), then converts that into the texture's RGBA level on the GPU (Espryt: `GL_EXT_YUV_target` with the import's colour hints, `MOBILEGL_YUV_DRIVER_CONVERSION=1` for the driver's external sampler; Magma: `VkSamplerYcbcrConversion` on the AHB's external format). A server-allocated NV12/P010 buffer (GBM `gbm_bo_create(NV12)`) needs no copy. `MOBILEGL_CHROME_VIDEO_DECODE=software` in `mobilegl-startup.sh chrome` brings back `--disable-accelerated-video-decode`. Check a video with `scripts/probes/cdpmedia.py ` in the container (CDP `Media.enable`: `kVideoDecoderName = VaapiVideoDecoder`, `kIsPlatformVideoDecoder = true`; `CDP_NAVIGATE=` / `CDP_EXPR=`), which needs Chrome started with `--remote-debugging-port` and a non-default `--user-data-dir` (a fresh profile also needs `--password-store=basic`, else page loads wait forever on KWallet), and grep Chrome's log for `exit_code` (a GPU-process restart). `scripts/probes/yuvprobe.c` pixel-checks foreign NV12/P010 imports, their per-frame refresh and a GBM NV12 buffer (`mgrun offscreen mgl-yuvprobe`, exit 0 = pass). KWin's own NV12 path (it splits a YUV buffer into R8 + GR88 imports) is not served: MobileGL imports no single-channel dma-bufs, so KWin advertises no YUV format over linux-dmabuf. A vendor-agnostic replacement driver (MobileVA: VA-API on Android MediaCodec, decoding into server YUV images with no CPU copy, the current driver kept as an A/B fallback) is planned, not built. +Video: Chrome decodes in hardware. The GPU process's render node has a VA-API driver in the container (`/usr/lib/dri/msm_drm_drv_video.so`, DroidSpaces' V4L2 driver): Chrome allocates its frames with `vaCreateSurfaces` and exports them (`vaExportSurfaceHandle`, one fd, R8 + GR88 layers) - the driver's own buffers, never GBM ones - and imports each as an NV12 (P010 for 10-bit) EGLImage bound to `GL_TEXTURE_EXTERNAL_OES`. MobileGL takes such a FOREIGN YUV dma-buf through its labeled CPU-copy fallback: the server maps it and copies it into a YUV AHardwareBuffer of its own (`AHardwareBuffer_lockPlanes`) at the reader's first use in each frame (any present, publishing flush or native fence), then converts that into the texture's RGBA level on the GPU (Espryt: `GL_EXT_YUV_target` with the import's color hints, `MOBILEGL_YUV_DRIVER_CONVERSION=1` for the driver's external sampler; Magma: `VkSamplerYcbcrConversion` on the AHB's external format). A server-allocated NV12/P010 buffer (GBM `gbm_bo_create(NV12)`) needs no copy. `MOBILEGL_CHROME_VIDEO_DECODE=software` in `mobilegl-startup.sh chrome` brings back `--disable-accelerated-video-decode`. Check a video with `scripts/probes/cdpmedia.py ` in the container (CDP `Media.enable`: `kVideoDecoderName = VaapiVideoDecoder`, `kIsPlatformVideoDecoder = true`; `CDP_NAVIGATE=` / `CDP_EXPR=`), which needs Chrome started with `--remote-debugging-port` and a non-default `--user-data-dir` (a fresh profile also needs `--password-store=basic`, else page loads wait forever on KWallet), and grep Chrome's log for `exit_code` (a GPU-process restart). `scripts/probes/yuvprobe.c` pixel-checks foreign NV12/P010 imports, their per-frame refresh and a GBM NV12 buffer (`mgrun offscreen mgl-yuvprobe`, exit 0 = pass). KWin's own NV12 path (it splits a YUV buffer into R8 + GR88 imports) is not served: MobileGL imports no single-channel dma-bufs, so KWin advertises no YUV format over linux-dmabuf. A vendor-agnostic replacement driver (MobileVA: VA-API on Android MediaCodec, decoding into server YUV images with no CPU copy, the current driver kept as an A/B fallback) is planned, not built. Device loss: `setprop debug.mobilegl.inject_device_lost_pid ` (as root) loses the server session of the client whose pid - as it sees itself in the container - is ``, once per value, on any backend and whether or not it presents; `debug.mobilegl.inject_device_lost_at N` instead loses whichever session makes the N-th device check (Espryt presents and read-backs only). `bash scripts/chrome-recover.sh [rounds]` checks that Chrome repaints after such a loss without a restart (battery-guarded, stops below 40%). `bash scripts/kwin-recover.sh [rounds]` loses KWin's own session (default twice) and checks that KWin restarts compositing on a fresh session - same KWin, plasmashell and client processes, the screen still animating (glmark2 on Wayland, glxgears on X11, `CHROME=1` adds Chrome) - which needs the anland backend + kwin.patch reset handling deployed (`kwin-stage.sh build`). Probes: `scripts/probes/texfmt.c` (texture formats keep alpha?), `dmahash.c` (hash a process's dma-bufs), `yuvprobe.c` (YUV dma-buf sampling, `gcc -O1 /root/yuvprobe.c -o /usr/local/bin/mgl-yuvprobe -lEGL -lGLESv2 -lgbm -lm`), `cdpmedia.py` (which decoder a Chrome page uses); build in the container, e.g. `gcc -O1 /root/texfmt.c -o /usr/local/bin/mgl-texfmt -lEGL`, run with `mgrun offscreen`. GPU hangs: a shader that never ends stops the WHOLE GPU (every process, MobileGL or not) until the kernel resets it - ~2 s, or ~10 s ("Preemption Fault" in dmesg) when a higher-priority context waits; nothing in user space shortens one stall. What the server does is end the guilty session so it cannot hang the GPU again (Magma: event-bracketed submissions + `mgl-gpu-watch`, budget `MOBILEGL_GPU_HANG_BUDGET_MS` / `debug.mobilegl.gpu_hang_budget_ms`, default 2000; Espryt: the driver's GUILTY reset status, which it reports after the ~2 s reset only). Repro: `scripts/probes/hangclient.c` (Wayland + GL 3.3 core; `-H 60 -N 1 -E 60` hangs every 60 frames, `-H -1` is a frame-gap observer; build with wayland-scanner's xdg-shell files, `-lwayland-client -lwayland-egl -lEGL -lOpenGL -lm`), and `gpuprobe.c` (NDK, plain adb shell; `gpuprobe 30 high` is a high-priority GLES context outside MobileGL - it both measures the device-wide stall and forces the 10 s preemption path). @@ -158,7 +158,7 @@ Reference (glmark2-es2-wayland 1280x720, zero-copy vs wl_shm): Espryt 187 vs 49, - **pkill -f self-match**: a `ct.sh`/`droidspaces run bash -lc "