Does updating a renderable's position while rendering it cause race condition? (Chapter 9 Scene Graph)

In the final project of Scene Graph, we have a function called func keyPressed(key: KeyboardControl, state: InputState) -> Bool where we updates the car’s position:

car.position = [0.35, -1, 0.1]
car.rotation = [0, 0, 0]

But we also constantly read the car’s position while we are rendering it.

Will this cause race condition? Do we need to avoid it?

This isn’t a race condition.

Scene’s update(deltaTime:) is called once per frame. It calls InputController’s updatePlayer(deltaTime:) which is where the position gets updated.

In a different thread, processEvent(key:state:) processes the keyboard input. directionKeysDown is a Set, so if you repeatedly press the w key, only one w value is retained.

InputController’s updatePlayer(deltaTime:) (being performed once per frame) takes that one w value and updates position.

Also, pressing a key is an I/O input signal sent to the CPU and has the lowest priority so it will be queued to be executed when all writes have finished. Also, CPU and GPU are so fast, that by the time you pressed w twice, multiple frames have already happened.

1 Like

I see. What if the car’s position is updated in func updateScene(deltaTime: Float) for every frame, without pressing any key or triggering pan gestures?

These updates are triggered by Scene’s update(deltaTime:), which happens once per frame before the draw. Whether you set the position in updatePlayer(deltaTime:) or updateScene(deltaTime), it doesn’t make any difference.

Also, position itself is not passed to the GPU. It is part of the model matrix that is passed.

Also, commandBuffer.waitUntilCompleted() at the end of draw(in:), means that everything stops until the GPU finishes its render. This isn’t the best way to synchronize between CPU and GPU.

Triple buffering (introduced later in the book) will solve this.

https://developer.apple.com/documentation/metal/synchronization/synchronizing_cpu_and_gpu_work

1 Like