Я пишу приложение для iOS с помощью Metal. В какой-то момент во время рисования MTKViewDelegate я создаю дескриптор прохода рендеринга и визуализирую вещи на экране,
let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
encoder.setViewport(camera.viewport)
encoder.setScissorRect(camera.scissorRect)
В начале моей функции рисования у меня есть семафор, тот же код, что и в шаблоне игры Metal, найденный в Xcode, а затем проверка, чтобы убедиться, что представление не изменило размер. Если это так, я воссоздаю свои буферы,
let w = _gBuffer?.width ?? 0
let h = _gBuffer?.height ?? 0
if let metalLayer = view.layer as? CAMetalLayer {
let size = metalLayer.drawableSize
if w != Int(size.width) || h != Int(size.height ){
_gBuffer = GBuffer(device: device, size: size)
}
}
Все работает нормально, и на моем iPhone6 вращение работало нормально. Однако, когда я пробовал на iPad Pro, он всегда генерировал SIGABRT, когда я пытаюсь повернуть устройство. Отладчик сообщает мне, что кодировщик обнулен. Я также получаю это исключение в консоли,
MTLDebugRenderCommandEncoder.mm:2028: failed assertion `(rect.x(1024) + rect.width(1024))(2048) must be <= 1536'
Исключение должно произойти, потому что я обновляю "камеру" внутри mtkView,
func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
camera.setBounds(view.bounds)
}
Когда я запускаю без подключенного отладчика, он не дает сбоев. Я предполагаю, что mtkView вызывается асинхронно, и я должен что-то сделать, чтобы остановить рендеринг на полпути, когда вызывается mtkView, но мьютекс должен быть в библиотеке, а не в моем коде? Хотя и draw, и mtkView вызываются из одного и того же потока (поток 1 в отладчике) ... Если я пошагово отлаживаю, помещая точки останова в рисование и mtkView, кажется, что я вручную синхронизирую, и он не падает. Я немного заблудился ...
Полный исходный код находится здесь: https://github.com/endavid/VidEngine
Любые идеи?