Changeset 269032 in webkit
- Timestamp:
- Oct 27, 2020 5:30:53 AM (3 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r269031 r269032 1 2020-10-15 Sergio Villar Senin <svillar@igalia.com> 2 3 [WebXR] Move OpenXR calls off the main thread 4 https://bugs.webkit.org/show_bug.cgi?id=217752 5 6 Reviewed by Youenn Fablet. 7 8 The OpenXR API is synchronous. Many of the calls involve dealing with external hardware devices 9 meaning that they have to potential to block the main thread. They should be moved to a different 10 thread in order to avoid that. 11 12 The PlatformXR::Instance creates a WorkQueue which is going to be used by the OpenXR devices to 13 issue OpenXR calls and also serialize them to ensure that they are executed sequentially. The 14 OpenXRDevice's are created in the main thread anyway because we need to get weak pointers from 15 them in the main thread. 16 17 * Modules/webxr/WebXRSystem.cpp: 18 (WebCore::WebXRSystem::ensureImmersiveXRDeviceIsSelected): Use a scoped exit to call callback. Also 19 the Vector of immersive devices is now a pointer which might be null, meaning no available devices. 20 * platform/xr/PlatformXR.h: Added a "using" for the Vector of devices. 21 * platform/xr/openxr/PlatformXROpenXR.cpp: 22 (PlatformXR::Instance::Impl::queue const): New getter returning the WorkQueue. 23 (PlatformXR::Instance::Impl::enumerateApiLayerProperties const): Added an ASSERT. 24 (PlatformXR::Instance::Impl::checkInstanceExtensionProperties const): Ditto. 25 (PlatformXR::Instance::Impl::Impl): Create the OpenXR WorkQueue and dispatch a task to perform the 26 OpenXR system initialization in the queue. 27 (PlatformXR::Instance::Impl::~Impl): Delete the instance in the WorkQueue 28 (PlatformXR::Instance::enumerateImmersiveXRDevices): Moved the code to a task in the WorkQueue. 29 (PlatformXR::OpenXRDevice::OpenXRDevice): Ditto. Also added a completion handler to notify the caller 30 about the end of the device initialization process. 31 (PlatformXR::OpenXRDevice::collectSupportedSessionModes): Added an ASSERT. 32 (PlatformXR::OpenXRDevice::collectConfigurationViews): Ditto. 33 * platform/xr/openxr/PlatformXROpenXR.h: Added WorkQueue attribute and parameter to device constructor. 34 1 35 2020-10-27 Xabier Rodriguez Calvar <calvaris@igalia.com> 2 36 -
trunk/Source/WebCore/Modules/webxr/WebXRSystem.cpp
r268700 r269032 89 89 m_immersiveXRDevicesHaveBeenEnumerated = true; 90 90 91 auto callbackOnExit = makeScopeExit([&]() { 92 callOnMainThread(WTFMove(callback)); 93 }); 94 91 95 // https://immersive-web.github.io/webxr/#select-an-immersive-xr-device 92 96 auto* oldDevice = m_activeImmersiveDevice.get(); 93 97 if (immersiveXRDevices.isEmpty()) { 94 98 m_activeImmersiveDevice = nullptr; 95 callback();96 99 return; 97 100 } 98 101 if (immersiveXRDevices.size() == 1) { 99 102 m_activeImmersiveDevice = makeWeakPtr(immersiveXRDevices.first().get()); 100 callback(); 101 return; 102 } 103 104 if (m_activeImmersiveSession && oldDevice && immersiveXRDevices.findMatching([&](auto& entry) { return entry.get() == oldDevice; }) != notFound) 103 return; 104 } 105 106 if (m_activeImmersiveSession && oldDevice && immersiveXRDevices.findMatching([&](auto& entry) { return &entry == oldDevice; }) != notFound) 105 107 ASSERT(m_activeImmersiveDevice.get() == oldDevice); 106 108 else { … … 110 112 111 113 if (isFirstXRDevicesEnumeration || m_activeImmersiveDevice.get() == oldDevice) { 112 callback();113 114 return; 114 115 } … … 117 118 // FIXME: 8. Set the XR compatible boolean of all WebGLRenderingContextBase instances to false. 118 119 // FIXME: 9. Queue a task to fire an event named devicechange on the context object. 119 120 callback();121 120 }); 122 121 } -
trunk/Source/WebCore/platform/xr/PlatformXR.h
r268255 r269032 76 76 static Instance& singleton(); 77 77 78 void enumerateImmersiveXRDevices(CompletionHandler<void(const Vector<std::unique_ptr<Device>>&)>&&); 78 using DeviceList = Vector<UniqueRef<Device>>; 79 void enumerateImmersiveXRDevices(CompletionHandler<void(const DeviceList&)>&&); 79 80 80 81 private: … … 86 87 UniqueRef<Impl> m_impl; 87 88 88 Vector<std::unique_ptr<Device>>m_immersiveXRDevices;89 DeviceList m_immersiveXRDevices; 89 90 }; 90 91 -
trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.cpp
r268255 r269032 74 74 #if USE_OPENXR 75 75 XrInstance xrInstance() const { return m_instance; } 76 WorkQueue& queue() const { return m_workQueue; } 76 77 #endif 77 78 … … 82 83 83 84 XrInstance m_instance { XR_NULL_HANDLE }; 85 Ref<WorkQueue> m_workQueue; 84 86 #endif // USE_OPENXR 85 87 }; … … 88 90 void Instance::Impl::enumerateApiLayerProperties() const 89 91 { 92 ASSERT(&RunLoop::current() == &m_workQueue->runLoop()); 90 93 uint32_t propertyCountOutput { 0 }; 91 94 XrResult result = xrEnumerateApiLayerProperties(0, &propertyCountOutput, nullptr); … … 120 123 bool Instance::Impl::checkInstanceExtensionProperties() const 121 124 { 125 ASSERT(&RunLoop::current() == &m_workQueue->runLoop()); 122 126 uint32_t propertyCountOutput { 0 }; 123 127 XrResult result = xrEnumerateInstanceExtensionProperties(nullptr, 0, &propertyCountOutput, nullptr); … … 155 159 156 160 Instance::Impl::Impl() 157 { 158 #if USE_OPENXR 159 LOG(XR, "OpenXR: initializing\n"); 160 161 enumerateApiLayerProperties(); 162 163 if (!checkInstanceExtensionProperties()) 164 return; 165 166 static const char* s_applicationName = "WebXR (WebKit)"; 167 static const uint32_t s_applicationVersion = 1; 168 169 const char* const enabledExtensions[] = { 170 XR_MND_HEADLESS_EXTENSION_NAME, 171 }; 172 173 auto createInfo = createStructure<XrInstanceCreateInfo, XR_TYPE_INSTANCE_CREATE_INFO>(); 174 createInfo.createFlags = 0; 175 std::memcpy(createInfo.applicationInfo.applicationName, s_applicationName, XR_MAX_APPLICATION_NAME_SIZE); 176 createInfo.applicationInfo.apiVersion = XR_CURRENT_API_VERSION; 177 createInfo.applicationInfo.applicationVersion = s_applicationVersion; 178 createInfo.enabledApiLayerCount = 0; 179 createInfo.enabledExtensionCount = WTF_ARRAY_LENGTH(enabledExtensions); 180 createInfo.enabledExtensionNames = enabledExtensions; 181 182 XrInstance instance; 183 XrResult result = xrCreateInstance(&createInfo, &instance); 184 RETURN_IF_FAILED(result, "xrCreateInstance()", m_instance); 185 m_instance = instance; 186 LOG(XR, "xrCreateInstance(): using instance %p\n", m_instance); 161 #if USE_OPENXR 162 : m_workQueue(WorkQueue::create("OpenXR queue")) 163 #endif 164 { 165 #if USE_OPENXR 166 m_workQueue->dispatch([this]() { 167 LOG(XR, "OpenXR: initializing\n"); 168 169 enumerateApiLayerProperties(); 170 171 if (!checkInstanceExtensionProperties()) 172 return; 173 174 static const char* s_applicationName = "WebXR (WebKit)"; 175 static const uint32_t s_applicationVersion = 1; 176 177 const char* const enabledExtensions[] = { 178 XR_MND_HEADLESS_EXTENSION_NAME, 179 }; 180 181 auto createInfo = createStructure<XrInstanceCreateInfo, XR_TYPE_INSTANCE_CREATE_INFO>(); 182 createInfo.createFlags = 0; 183 std::memcpy(createInfo.applicationInfo.applicationName, s_applicationName, XR_MAX_APPLICATION_NAME_SIZE); 184 createInfo.applicationInfo.apiVersion = XR_CURRENT_API_VERSION; 185 createInfo.applicationInfo.applicationVersion = s_applicationVersion; 186 createInfo.enabledApiLayerCount = 0; 187 createInfo.enabledExtensionCount = WTF_ARRAY_LENGTH(enabledExtensions); 188 createInfo.enabledExtensionNames = enabledExtensions; 189 190 XrInstance instance; 191 XrResult result = xrCreateInstance(&createInfo, &instance); 192 RETURN_IF_FAILED(result, "xrCreateInstance()", m_instance); 193 m_instance = instance; 194 LOG(XR, "xrCreateInstance(): using instance %p\n", m_instance); 195 }); 187 196 #endif // USE_OPENXR 188 197 } … … 191 200 { 192 201 #if USE_OPENXR 193 if (m_instance != XR_NULL_HANDLE) 194 xrDestroyInstance(m_instance); 202 m_workQueue->dispatch([this] { 203 if (m_instance != XR_NULL_HANDLE) 204 xrDestroyInstance(m_instance); 205 }); 195 206 #endif 196 207 } … … 212 223 } 213 224 214 void Instance::enumerateImmersiveXRDevices(CompletionHandler<void(const Vector<std::unique_ptr<Device>>& devices)>&& callback) 215 { 216 #if USE_OPENXR 217 auto callbackOnExit = makeScopeExit([&]() { 218 callback({ }); 225 void Instance::enumerateImmersiveXRDevices(CompletionHandler<void(const DeviceList& devices)>&& callback) 226 { 227 #if USE_OPENXR 228 m_impl->queue().dispatch([this, callback = WTFMove(callback)]() mutable { 229 auto callbackOnExit = makeScopeExit([&]() { 230 callOnMainThread([callback = WTFMove(callback)]() mutable { 231 callback({ }); 232 }); 233 }); 234 235 if (m_impl->xrInstance() == XR_NULL_HANDLE) { 236 LOG(XR, "%s Unable to enumerate XR devices. No XrInstance present\n", __FUNCTION__); 237 return; 238 } 239 240 auto systemGetInfo = createStructure<XrSystemGetInfo, XR_TYPE_SYSTEM_GET_INFO>(); 241 systemGetInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; 242 243 XrSystemId systemId; 244 XrResult result = xrGetSystem(m_impl->xrInstance(), &systemGetInfo, &systemId); 245 RETURN_IF_FAILED(result, "xrGetSystem", m_impl->xrInstance()); 246 247 callbackOnExit.release(); 248 249 callOnMainThread([this, callback = WTFMove(callback), systemId]() mutable { 250 m_immersiveXRDevices = DeviceList::from(makeUniqueRef<OpenXRDevice>(systemId, m_impl->xrInstance(), m_impl->queue(), [this, callback = WTFMove(callback)]() mutable { 251 ASSERT(isMainThread()); 252 callback(m_immersiveXRDevices); 253 })); 254 }); 219 255 }); 220 if (m_impl->xrInstance() == XR_NULL_HANDLE) { 221 LOG(XR, "%s Unable to enumerate XR devices. No XrInstance present\n", __FUNCTION__); 222 return; 223 } 224 225 auto systemGetInfo = createStructure<XrSystemGetInfo, XR_TYPE_SYSTEM_GET_INFO>(); 226 systemGetInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; 227 228 XrSystemId systemId; 229 XrResult result = xrGetSystem(m_impl->xrInstance(), &systemGetInfo, &systemId); 230 RETURN_IF_FAILED(result, "xrGetSystem", m_impl->xrInstance()); 231 256 257 #endif // USE_OPENXR 258 } 259 260 #if USE_OPENXR 261 OpenXRDevice::OpenXRDevice(XrSystemId id, XrInstance instance, WorkQueue& queue, CompletionHandler<void()>&& callback) 262 : m_systemId(id) 263 , m_instance(instance) 264 , m_queue(queue) 265 { 266 ASSERT(isMainThread()); 267 m_queue.dispatch([this, callback = WTFMove(callback)]() mutable { 268 auto systemProperties = createStructure<XrSystemProperties, XR_TYPE_SYSTEM_PROPERTIES>(); 269 auto result = xrGetSystemProperties(m_instance, m_systemId, &systemProperties); 270 if (XR_SUCCEEDED(result)) 271 m_supportsOrientationTracking = systemProperties.trackingProperties.orientationTracking == XR_TRUE; 232 272 #if !LOG_DISABLED 233 auto systemProperties = createStructure<XrSystemProperties, XR_TYPE_SYSTEM_PROPERTIES>(); 234 result = xrGetSystemProperties(m_impl->xrInstance(), systemId, &systemProperties); 235 if (result == XR_SUCCESS) 273 else 274 LOG(XR, "xrGetSystemProperties(): error %s\n", resultToString(result, m_instance).utf8().data()); 236 275 LOG(XR, "Found XRSystem %lu: \"%s\", vendor ID %d\n", systemProperties.systemId, systemProperties.systemName, systemProperties.vendorId); 237 276 #endif 238 277 239 m_immersiveXRDevices.append(makeUnique<OpenXRDevice>(systemId, m_impl->xrInstance())); 240 callback(m_immersiveXRDevices); 241 callbackOnExit.release(); 242 #endif // USE_OPENXR 243 } 244 245 #if USE_OPENXR 246 OpenXRDevice::OpenXRDevice(XrSystemId id, XrInstance instance) 247 : m_systemId(id) 248 , m_instance(instance) 249 { 250 auto systemProperties = createStructure<XrSystemProperties, XR_TYPE_SYSTEM_PROPERTIES>(); 251 XrResult result = xrGetSystemProperties(instance, m_systemId, &systemProperties); 252 if (result == XR_SUCCESS) 253 m_supportsOrientationTracking = systemProperties.trackingProperties.orientationTracking == XR_TRUE; 254 else 255 LOG(XR, "xrGetSystemProperties(): error %s\n", resultToString(result, m_instance).utf8().data()); 256 257 collectSupportedSessionModes(); 258 collectConfigurationViews(); 278 collectSupportedSessionModes(); 279 collectConfigurationViews(); 280 281 callOnMainThread(WTFMove(callback)); 282 }); 259 283 } 260 284 … … 300 324 void OpenXRDevice::collectSupportedSessionModes() 301 325 { 326 ASSERT(&RunLoop::current() == &m_queue.runLoop()); 302 327 uint32_t viewConfigurationCount; 303 328 auto result = xrEnumerateViewConfigurations(m_instance, m_systemId, 0, &viewConfigurationCount, nullptr); … … 342 367 void OpenXRDevice::collectConfigurationViews() 343 368 { 369 ASSERT(&RunLoop::current() == &m_queue.runLoop()); 344 370 for (auto& config : m_viewConfigurationProperties.values()) { 345 371 uint32_t viewCount; -
trunk/Source/WebCore/platform/xr/openxr/PlatformXROpenXR.h
r265137 r269032 27 27 #if USE_OPENXR 28 28 #include <openxr/openxr.h> 29 #include <wtf/WorkQueue.h> 29 30 30 31 namespace PlatformXR { … … 44 45 class OpenXRDevice final : public Device { 45 46 public: 46 OpenXRDevice(XrSystemId, XrInstance );47 OpenXRDevice(XrSystemId, XrInstance, WorkQueue&, CompletionHandler<void()>&&); 47 48 XrSystemId xrSystemId() const { return m_systemId; } 49 48 50 private: 49 51 void collectSupportedSessionModes(); … … 62 64 XrInstance m_instance; 63 65 XrSession m_session; 66 67 WorkQueue& m_queue; 64 68 }; 65 69
Note: See TracChangeset
for help on using the changeset viewer.