Bug 230630 - [WPE] Add gamepad support
Summary: [WPE] Add gamepad support
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore Misc. (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Víctor M. Jáquez L.
URL:
Keywords: InRadar
Depends on: 243822 244245
Blocks:
  Show dependency treegraph
 
Reported: 2021-09-22 09:44 PDT by Víctor M. Jáquez L.
Modified: 2022-08-24 04:13 PDT (History)
10 users (show)

See Also:


Attachments
Patch (30.23 KB, patch)
2021-09-23 03:51 PDT, Víctor M. Jáquez L.
no flags Details | Formatted Diff | Diff
Patch (31.73 KB, patch)
2021-09-23 10:54 PDT, Víctor M. Jáquez L.
no flags Details | Formatted Diff | Diff
Patch (32.51 KB, patch)
2022-02-10 04:31 PST, Víctor M. Jáquez L.
no flags Details | Formatted Diff | Diff
Patch (32.15 KB, patch)
2022-05-04 11:59 PDT, Víctor M. Jáquez L.
no flags Details | Formatted Diff | Diff
Patch (33.22 KB, patch)
2022-05-10 04:22 PDT, Víctor M. Jáquez L.
vjaquez: review?
ews-feeder: commit-queue-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Víctor M. Jáquez L. 2021-09-22 09:44:12 PDT
Add gamepad support through libwpe.
Comment 1 Víctor M. Jáquez L. 2021-09-23 03:51:02 PDT
Created attachment 439033 [details]
Patch
Comment 2 Víctor M. Jáquez L. 2021-09-23 10:54:17 PDT
Created attachment 439064 [details]
Patch
Comment 3 Carlos Alberto Lopez Perez 2021-11-12 10:55:30 PST
Patch failed to build on the WPE EWS

Is because it needs https://github.com/WebPlatformForEmbedded/libwpe/pull/88 into libwpe?
Comment 4 Víctor M. Jáquez L. 2021-11-12 20:12:00 PST
(In reply to Carlos Alberto Lopez Perez from comment #3)
> Patch failed to build on the WPE EWS
> 
> Is because it needs https://github.com/WebPlatformForEmbedded/libwpe/pull/88
> into libwpe?

Yes, that API is required.
Comment 5 Zan Dobersek 2021-11-14 23:51:29 PST
Comment on attachment 439064 [details]
Patch

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

> Source/WebKit/UIProcess/API/wpe/WPEView.cpp:467
> +#if ENABLE(GAMEPAD)
> +WebKit::WebPageProxy* View::platformWebPageProxyForGamepadInput()
> +{
> +    const auto& views = viewsVector();
> +    if (views.isEmpty())
> +        return nullptr;
> +
> +    auto index = views.findMatching([](View* view) {
> +        return view->viewState().contains(WebCore::ActivityState::IsVisible)
> +            && view->viewState().contains(WebCore::ActivityState::IsFocused);
> +    });
> +
> +    if (index != notFound)
> +        return &(views[index]->page());
> +
> +    return nullptr;
> +}
> +#endif

This is not ideal. The wpe_gamepad API should be handled so that the embedding application has the control over what view the provider is assigned to, and covering the possibility of that provider being assigned to a different view during its lifetime.
Comment 6 Víctor M. Jáquez L. 2021-11-17 10:05:59 PST
(In reply to Zan Dobersek from comment #5)
> Comment on attachment 439064 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=439064&action=review
> 
> > Source/WebKit/UIProcess/API/wpe/WPEView.cpp:467
> > +#if ENABLE(GAMEPAD)
> > +WebKit::WebPageProxy* View::platformWebPageProxyForGamepadInput()
> > +{
> > +    const auto& views = viewsVector();
> > +    if (views.isEmpty())
> > +        return nullptr;
> > +
> > +    auto index = views.findMatching([](View* view) {
> > +        return view->viewState().contains(WebCore::ActivityState::IsVisible)
> > +            && view->viewState().contains(WebCore::ActivityState::IsFocused);
> > +    });
> > +
> > +    if (index != notFound)
> > +        return &(views[index]->page());
> > +
> > +    return nullptr;
> > +}
> > +#endif
> 
> This is not ideal. The wpe_gamepad API should be handled so that the
> embedding application has the control over what view the provider is
> assigned to, and covering the possibility of that provider being assigned to
> a different view during its lifetime.

Right.
Comment 7 Víctor M. Jáquez L. 2022-02-10 04:31:41 PST
Created attachment 451516 [details]
Patch
Comment 8 Víctor M. Jáquez L. 2022-03-08 07:19:40 PST
 (In reply to Zan Dobersek from comment #5)
>
> This is not ideal. The wpe_gamepad API should be handled so that the
> embedding application has the control over what view the provider is
> assigned to, and covering the possibility of that provider being assigned to
> a different view during its lifetime.

I guess this request is now addressed. So, gently ping :)

Remind this patch needs: https://github.com/WebPlatformForEmbedded/libwpe/pull/88

And, to test it in cog: https://github.com/Igalia/cog/pull/361
Comment 9 Adrian Perez 2022-05-04 06:45:40 PDT
Comment on attachment 451516 [details]
Patch

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

Other than a few suggestions here and there, this is looking quite good to me.
Probably we can merge it after a round of polish :-)

> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:48
> +    static struct wpe_gamepad_client_interface s_client = {

This can be “static const”.

> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:51
> +            auto& self = *reinterpret_cast<WPEGamepad*>(data);

Use static_cast<WPEGamepad*> here.

> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:57
> +            auto& self = *reinterpret_cast<WPEGamepad*>(data);

Same here, use static_cast<WPEGamepad*>.

> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:66
> +        value.setValue(0.0);

There is a Vector(value, size) constructor that can be used initialize this
automatically during construction, without needing an explicit resize+loop.
See note below.

> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:76
> +        return;

I would actually ASSERT(!m_gamepad) because the pointer is always
initialized in the constructor, so unless something weird happens the
pointer should always be valid during the lifetime of the WPEGamepad
instance.

> Source/WebCore/platform/gamepad/wpe/WPEGamepad.h:51
> +    Vector<SharedGamepadValue> m_buttonValues;

Given that GAMEPAD_BUTTON_COUNT is a constant, this could be a
Vector<SharedGamepadValue, GAMEPAD_BUTTON_COUNT> to store the
values inline inside the WPEGamepad. As a side effect that avoids
a heap allocation and has better cache locality (less pointer chasing).

Also you can do the initialization here:

    Vector<SharedGamepadValue, GAMEPAD_BUTTON_COUNT> m_buttonValues { GAMEPAD_BUTTON_COUNT, 0.0 };

> Source/WebCore/platform/gamepad/wpe/WPEGamepad.h:54
> +    struct wpe_gamepad* m_gamepad { nullptr };

How about using a std::unique_ptr<struct wpe_gamepad, wpe_gamepad_destroy> here?

> Source/WebCore/platform/gamepad/wpe/WPEGamepadProvider.cpp:57
> +    static struct wpe_gamepad_provider_client_interface s_client = {

This can be “static const”.

> Source/WebCore/platform/gamepad/wpe/WPEGamepadProvider.cpp:60
> +            auto& provider = *reinterpret_cast<WPEGamepadProvider*>(data);

static_cast

> Source/WebCore/platform/gamepad/wpe/WPEGamepadProvider.cpp:65
> +            auto& provider = *reinterpret_cast<WPEGamepadProvider*>(data);

static_cast

> Source/WebCore/platform/gamepad/wpe/WPEGamepadProvider.cpp:155
> +void WPEGamepadProvider::gamepadDiconnected(unsigned id)

Typo: gamepadDiconnected -> gamepadDisconnected

> Source/WebKit/UIProcess/API/wpe/WPEView.cpp:54
> +}

I'm not much of a fan of adding global data, but I would need to think a
bit to try to come up with some alternative. Right not I don't have anything
from the top of my head, and this definitely works, so I won't ask to change
it 😉️
Comment 10 Víctor M. Jáquez L. 2022-05-04 11:38:11 PDT
Comment on attachment 451516 [details]
Patch

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

>> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:48
>> +    static struct wpe_gamepad_client_interface s_client = {
> 
> This can be “static const”.

it cannot be const because the function's signature for wpe_gamepad_set_client isn't either.

>> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:51
>> +            auto& self = *reinterpret_cast<WPEGamepad*>(data);
> 
> Use static_cast<WPEGamepad*> here.

done

>> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:57
>> +            auto& self = *reinterpret_cast<WPEGamepad*>(data);
> 
> Same here, use static_cast<WPEGamepad*>.

done

>> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:66
>> +        value.setValue(0.0);
> 
> There is a Vector(value, size) constructor that can be used initialize this
> automatically during construction, without needing an explicit resize+loop.
> See note below.

I didn't initialized it in the header but in the class constructor, because libwpe.h enums aren't exposed in the header file.

>> Source/WebCore/platform/gamepad/wpe/WPEGamepad.cpp:76
>> +        return;
> 
> I would actually ASSERT(!m_gamepad) because the pointer is always
> initialized in the constructor, so unless something weird happens the
> pointer should always be valid during the lifetime of the WPEGamepad
> instance.

added the ASSERT

>> Source/WebCore/platform/gamepad/wpe/WPEGamepad.h:51
>> +    Vector<SharedGamepadValue> m_buttonValues;
> 
> Given that GAMEPAD_BUTTON_COUNT is a constant, this could be a
> Vector<SharedGamepadValue, GAMEPAD_BUTTON_COUNT> to store the
> values inline inside the WPEGamepad. As a side effect that avoids
> a heap allocation and has better cache locality (less pointer chasing).
> 
> Also you can do the initialization here:
> 
>     Vector<SharedGamepadValue, GAMEPAD_BUTTON_COUNT> m_buttonValues { GAMEPAD_BUTTON_COUNT, 0.0 };

I used the initializator but not in this way, because of the libwpe.h header inclusion.

>> Source/WebCore/platform/gamepad/wpe/WPEGamepad.h:54
>> +    struct wpe_gamepad* m_gamepad { nullptr };
> 
> How about using a std::unique_ptr<struct wpe_gamepad, wpe_gamepad_destroy> here?

done

Also for the wpe_gamepad_provider. Though, didn't include the function there, but in the initializator in class consturctor.

>> Source/WebCore/platform/gamepad/wpe/WPEGamepadProvider.cpp:57
>> +    static struct wpe_gamepad_provider_client_interface s_client = {
> 
> This can be “static const”.

As  in wpe_gamepad, it cannot be const because of the wpe's function signature.

>> Source/WebCore/platform/gamepad/wpe/WPEGamepadProvider.cpp:60
>> +            auto& provider = *reinterpret_cast<WPEGamepadProvider*>(data);
> 
> static_cast

done

>> Source/WebCore/platform/gamepad/wpe/WPEGamepadProvider.cpp:65
>> +            auto& provider = *reinterpret_cast<WPEGamepadProvider*>(data);
> 
> static_cast

done

>> Source/WebCore/platform/gamepad/wpe/WPEGamepadProvider.cpp:155
>> +void WPEGamepadProvider::gamepadDiconnected(unsigned id)
> 
> Typo: gamepadDiconnected -> gamepadDisconnected

done! hehehe

>> Source/WebKit/UIProcess/API/wpe/WPEView.cpp:54
>> +}
> 
> I'm not much of a fan of adding global data, but I would need to think a
> bit to try to come up with some alternative. Right not I don't have anything
> from the top of my head, and this definitely works, so I won't ask to change
> it 😉️

ok :)
Comment 11 Víctor M. Jáquez L. 2022-05-04 11:59:32 PDT
Created attachment 458817 [details]
Patch
Comment 12 Víctor M. Jáquez L. 2022-05-04 12:00:43 PDT
We need to talk how and when merge this because of the version bumps needed for cog and libwpe.
Comment 13 Víctor M. Jáquez L. 2022-05-10 01:20:59 PDT
(In reply to Víctor M. Jáquez L. from comment #12)
> We need to talk how and when merge this because of the version bumps needed
> for cog and libwpe.

There's an interesting situation here: WebXR WPE implementation also has its own gamepad implementation, through OpenXR, but it excludes the html gamepad. It's specific to WebXR.

It brings some questions:

1\ Doesn't both implementations step one over the other?
2\ If user disable gamepad, it's enabled for WebXR silently
3\ There's not a implicit feature mechanism to disable one but enabling the other.
Comment 14 Víctor M. Jáquez L. 2022-05-10 04:22:33 PDT
Created attachment 459107 [details]
Patch
Comment 15 Víctor M. Jáquez L. 2022-05-23 05:09:01 PDT
Pull request: https://github.com/WebKit/WebKit/pull/911
Comment 16 EWS 2022-08-24 04:12:34 PDT
Committed 253720@main (ab0e24752e11): <https://commits.webkit.org/253720@main>

Reviewed commits have been landed. Closing PR #911 and removing active labels.
Comment 17 Radar WebKit Bug Importer 2022-08-24 04:13:44 PDT
<rdar://problem/99078410>