Bug 184530 - [WebVR][OpenVR] Implement requestPresent()/exitPresent() and getLayers()
Summary: [WebVR][OpenVR] Implement requestPresent()/exitPresent() and getLayers()
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Sergio Villar Senin
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-04-12 03:13 PDT by Sergio Villar Senin
Modified: 2018-04-13 08:20 PDT (History)
8 users (show)

See Also:


Attachments
Patch (9.54 KB, patch)
2018-04-12 03:29 PDT, Sergio Villar Senin
no flags Details | Formatted Diff | Diff
Patch (9.53 KB, patch)
2018-04-12 04:56 PDT, Sergio Villar Senin
no flags Details | Formatted Diff | Diff
Patch (8.97 KB, patch)
2018-04-13 04:59 PDT, Sergio Villar Senin
no flags Details | Formatted Diff | Diff
Patch (8.82 KB, patch)
2018-04-13 07:16 PDT, Sergio Villar Senin
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergio Villar Senin 2018-04-12 03:13:11 PDT
[WebVR][OpenVR] Implement requestPresent()/exitPresent() and getLayers()
Comment 1 Sergio Villar Senin 2018-04-12 03:29:05 PDT
Created attachment 337784 [details]
Patch
Comment 2 Sergio Villar Senin 2018-04-12 04:56:46 PDT
Created attachment 337787 [details]
Patch

rebased patch
Comment 3 Zan Dobersek 2018-04-12 10:14:28 PDT
Comment on attachment 337787 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=337787&action=review

> Source/WebCore/Modules/webvr/VRDisplay.cpp:143
> +    Ref<DeferredPromise> promise = WTFMove(deferredPromise);

Is this necessary? It usually isn't.

> Source/WebCore/Modules/webvr/VRDisplay.cpp:161
> +    RELEASE_ASSERT(layers.size() == 1);
> +    auto layer = layers[0];

This should handle more than one layer at some point, right? But it's currently limited to the maxLayers() value in VRDisplayCapabilities?

> Source/WebCore/Modules/webvr/VRDisplay.cpp:168
> +    if (!layer.source->getContext("webgl")->isWebGL()) {

This should handle HTMLCanvas::getContext() returning nullptr.

> Source/WebCore/Modules/webvr/VRDisplay.h:123
> +    bool m_isPresenting;
> +    std::optional<VRLayerInit> m_presentingLayer;

Can m_isPresenting be deduced from m_presentingLayer being non-nullopt wherever it's used.
Comment 4 Zan Dobersek 2018-04-12 11:01:43 PDT
Comment on attachment 337787 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=337787&action=review

>> Source/WebCore/Modules/webvr/VRDisplay.h:123
>> +    std::optional<VRLayerInit> m_presentingLayer;
> 
> Can m_isPresenting be deduced from m_presentingLayer being non-nullopt wherever it's used.

i.e, an m_isPresenting be eliminated?
Comment 5 Sergio Villar Senin 2018-04-13 03:39:46 PDT
Comment on attachment 337787 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=337787&action=review

>> Source/WebCore/Modules/webvr/VRDisplay.cpp:143
>> +    Ref<DeferredPromise> promise = WTFMove(deferredPromise);
> 
> Is this necessary? It usually isn't.

No, not really

>> Source/WebCore/Modules/webvr/VRDisplay.cpp:161
>> +    auto layer = layers[0];
> 
> This should handle more than one layer at some point, right? But it's currently limited to the maxLayers() value in VRDisplayCapabilities?

Not in WebVR 1.1. As you can see in the spec (https://immersive-web.github.io/webvr/spec/1.1/#vrdisplaycapabilities-attributes) 

"maxLayers Indicates the maximum length of the array that requestPresent() will accept. MUST be 1 if canPresent is true, 0 otherwise."

In the next specification, WebXR, maxLayers() does not exist for example.

>> Source/WebCore/Modules/webvr/VRDisplay.cpp:168
>> +    if (!layer.source->getContext("webgl")->isWebGL()) {
> 
> This should handle HTMLCanvas::getContext() returning nullptr.

Right.

>>> Source/WebCore/Modules/webvr/VRDisplay.h:123
>>> +    std::optional<VRLayerInit> m_presentingLayer;
>> 
>> Can m_isPresenting be deduced from m_presentingLayer being non-nullopt wherever it's used.
> 
> i.e, an m_isPresenting be eliminated?

So far yes. I was just not sure and decided to play safe, but I can remove it now and add it later if needed.
Comment 6 Zan Dobersek 2018-04-13 03:49:52 PDT
Comment on attachment 337787 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=337787&action=review

>>>> Source/WebCore/Modules/webvr/VRDisplay.h:123
>>>> +    std::optional<VRLayerInit> m_presentingLayer;
>>> 
>>> Can m_isPresenting be deduced from m_presentingLayer being non-nullopt wherever it's used.
>> 
>> i.e, an m_isPresenting be eliminated?
> 
> So far yes. I was just not sure and decided to play safe, but I can remove it now and add it later if needed.

Let's keep this extra boolean for now then, and remove it and simplify things around it when it's determined to not be required.
Comment 7 Sergio Villar Senin 2018-04-13 04:59:41 PDT
Created attachment 337881 [details]
Patch
Comment 8 Zan Dobersek 2018-04-13 05:48:19 PDT
Comment on attachment 337881 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=337881&action=review

> Source/WebCore/Modules/webvr/VRDisplay.cpp:138
> +void VRDisplay::rejectRequestAndStopPresenting(Ref<DeferredPromise>& promise, ExceptionCode exceptionCode, const String& message)
> +{
> +    promise->reject(Exception { exceptionCode, message });
> +    if (m_presentingLayer)
> +        stopPresenting();
> +}

Given this method is specific to requestPresent(), it might fit better as a local lambda. But it's not super-important.

> Source/WebCore/Modules/webvr/VRDisplay.cpp:184
> +void VRDisplay::stopPresenting()
>  {
> +    m_presentingLayer = std::nullopt;
>  }

Given this is now a one-liner, m_presentingLayer could just be nulled out eveywhere instead of having to call this method.
Comment 9 Zan Dobersek 2018-04-13 05:50:18 PDT
Comment on attachment 337881 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=337881&action=review

> Source/WebCore/Modules/webvr/VRDisplay.cpp:141
> +void VRDisplay::requestPresent(const Vector<VRLayerInit>& layers, Ref<DeferredPromise>&& promise)
> +{

OTOH, this method is guaranteed to either null out the m_presentingLayer value or replace it with the passed-in object. If you null out m_presentingLayer at the beginning, you can replace rejectRequestAndStopPresenting() with direct `promise->reject()` calls and stop calling `stopPresenting()`.
Comment 10 Sergio Villar Senin 2018-04-13 06:46:23 PDT
Comment on attachment 337881 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=337881&action=review

>> Source/WebCore/Modules/webvr/VRDisplay.cpp:138
>> +}
> 
> Given this method is specific to requestPresent(), it might fit better as a local lambda. But it's not super-important.

Makes sense indeed.

>> Source/WebCore/Modules/webvr/VRDisplay.cpp:141
>> +{
> 
> OTOH, this method is guaranteed to either null out the m_presentingLayer value or replace it with the passed-in object. If you null out m_presentingLayer at the beginning, you can replace rejectRequestAndStopPresenting() with direct `promise->reject()` calls and stop calling `stopPresenting()`.

With the current code that's true, but when we add the required code to effectively render the layer content in the HMD, stopPresenting() would likely have to do more things.

Now that I think about it, the specs mandate us to reject the promise in all the cases listed bellow but they don't specify that the presentation should be stopped, I'll change that.

>> Source/WebCore/Modules/webvr/VRDisplay.cpp:184
>>  }
> 
> Given this is now a one-liner, m_presentingLayer could just be nulled out eveywhere instead of having to call this method.

I know but I we'd have to do more things whenever we integrate the requestPresent with the underlying SDK, i.e., when we effectively start using the passed in layer to render stereo content in the HMD
Comment 11 Sergio Villar Senin 2018-04-13 06:52:20 PDT
(In reply to Sergio Villar Senin from comment #10) 
> Now that I think about it, the specs mandate us to reject the promise in all
> the cases listed bellow but they don't specify that the presentation should
> be stopped, I'll change that.

Nah, the code is correct. Literally from specs "If a call to requestPresent() is rejected while the VRDisplay is already presenting, the VRDisplay MUST end presentation."
Comment 12 Sergio Villar Senin 2018-04-13 07:16:26 PDT
Created attachment 337885 [details]
Patch

Patch for landing
Comment 13 Sergio Villar Senin 2018-04-13 08:19:07 PDT
Committed r230630: <https://trac.webkit.org/changeset/230630>
Comment 14 Radar WebKit Bug Importer 2018-04-13 08:20:22 PDT
<rdar://problem/39412653>