SpatialSurfaceObserver::GetObservedSurfaces() занимает много времени и блокирует рендеринг
У меня есть приложение Hololens, написанное на C++/WinRT, которое запрашивает пространственные поверхности, используя SpatialSurfaceObserver
, Для этого приложение отвечает ObservedSurfacesChanged
событие и там запускается функция, которая получает список пространственных сеток с GetObservedSurfaces
, Затем для каждой записи строится и отображается сетка.
У меня проблемы с звонками GetObservedSurfaces
, Измерения показывают, что он обычно работает в течение 120-140 миллисекунд. Первые несколько запусков после запуска приложения занимают почти 500 миллисекунд. Само по себе это может быть приемлемым. Тем не менее, кажется, что вызов блокирует все приложение до его возврата, что приводит к тому, что цикл рендеринга отбрасывает несколько кадров, разрушая пользовательский опыт. Нет блокировки, которая бы заморозила приложение, пока MyApp::UpdateSpatialMeshes
бежит. Если я заменю звонок auto surfaces = observer.GetObservedSurfaces();
с простым ожиданием в одну секунду (и закомментируйте все в зависимости от surfaces
) все нормально без пропадания кадров происходит.
У кого-нибудь есть идея, почему GetObservedSurfaces
блокирует мое приложение или что я могу сделать, чтобы использовать его более правильно?
ОБНОВЛЕНИЕ: Есть ок. 40 поверхностных сеток в возвращенной коллекции, содержащей ~100 тыс. Треугольников.
Инициализация:
winrt::Windows::Foundation::IAsyncAction MyApp::InitSurfaceObserver()
{
co_await winrt::resume_background();
auto status = co_await SpatialSurfaceObserver::RequestAccessAsync();
if (status == SpatialPerceptionAccessStatus::Allowed)
{
auto coordSys = m_stationaryReferenceFrame.CoordinateSystem();
m_surfaceObserver = SpatialSurfaceObserver();
m_surfaceObserver.ObservedSurfacesChanged([this](auto&& sender, auto&& args)
{
UpdateSpatialMeshes(m_surfaceObserver, coordSys); // runs in background
});
SpatialBoundingBox aabb = { { 0.0f, 0.0f, 0.0f }, { 20.0f, 20.0f, 5.0f } };
auto bounds = SpatialBoundingVolume::FromBox(coordSys, aabb);
m_surfaceObserver.SetBoundingVolume(bounds);
}
// else: complain
}
Обработка:
winrt::fire_and_forget MyApp::UpdateSpatialMeshes(const SpatialCoordinateSystem& coordSys,
const SpatialSurfaceObserver& observer)
{
if (coordSys /* AND no other UpdateSpatialMeshes is currently running*/)
{
SpatialCoordinateSystem scs{ coordSys }; // back up the coordinate system
co_await winrt::resume_background();
auto surfaces = observer.GetObservedSurfaces(); // <<< FREEZES EVERYTHING
for (auto const& pair : surfaces)
{
const GUID& id = pair.Key();
auto surfaceInfo = pair.Value();
if (!surfaceInfo) continue;
// TryComputeLatestMeshAsync, then render
}
}
}