diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/Gamepad')
-rw-r--r-- | Source/WebKit2/UIProcess/Gamepad/UIGamepad.cpp | 73 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/Gamepad/UIGamepad.h | 62 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp | 251 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h | 95 |
4 files changed, 481 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/Gamepad/UIGamepad.cpp b/Source/WebKit2/UIProcess/Gamepad/UIGamepad.cpp new file mode 100644 index 000000000..5c0b320f8 --- /dev/null +++ b/Source/WebKit2/UIProcess/Gamepad/UIGamepad.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "UIGamepad.h" + +#if ENABLE(GAMEPAD) + +#include "GamepadData.h" +#include <WebCore/PlatformGamepad.h> + +using namespace WebCore; + +namespace WebKit { + +UIGamepad::UIGamepad(WebCore::PlatformGamepad& platformGamepad) + : m_index(platformGamepad.index()) + , m_id(platformGamepad.id()) + , m_lastUpdateTime(platformGamepad.lastUpdateTime()) +{ + m_axisValues.resize(platformGamepad.axisValues().size()); + m_buttonValues.resize(platformGamepad.buttonValues().size()); + + updateFromPlatformGamepad(platformGamepad); +} + +void UIGamepad::updateFromPlatformGamepad(WebCore::PlatformGamepad& platformGamepad) +{ + ASSERT(m_index == platformGamepad.index()); + ASSERT(m_axisValues.size() == platformGamepad.axisValues().size()); + ASSERT(m_buttonValues.size() == platformGamepad.buttonValues().size()); + + m_axisValues = platformGamepad.axisValues(); + m_buttonValues = platformGamepad.buttonValues(); + m_lastUpdateTime = platformGamepad.lastUpdateTime(); +} + +GamepadData UIGamepad::condensedGamepadData() const +{ + return { m_index, m_axisValues, m_buttonValues, m_lastUpdateTime }; +} + +GamepadData UIGamepad::fullGamepadData() const +{ + return { m_index, m_id, m_axisValues, m_buttonValues, m_lastUpdateTime }; +} + + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebKit2/UIProcess/Gamepad/UIGamepad.h b/Source/WebKit2/UIProcess/Gamepad/UIGamepad.h new file mode 100644 index 000000000..0c47e8561 --- /dev/null +++ b/Source/WebKit2/UIProcess/Gamepad/UIGamepad.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(GAMEPAD) + +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { +class PlatformGamepad; +} + +namespace WebKit { + +class GamepadData; + +class UIGamepad { +public: + UIGamepad(WebCore::PlatformGamepad&); + + unsigned index() const { return m_index; } + + GamepadData condensedGamepadData() const; + GamepadData fullGamepadData() const; + + void updateFromPlatformGamepad(WebCore::PlatformGamepad&); + +private: + unsigned m_index; + String m_id; + Vector<double> m_axisValues; + Vector<double> m_buttonValues; + double m_lastUpdateTime; +}; + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp b/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp new file mode 100644 index 000000000..657c416f9 --- /dev/null +++ b/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "UIGamepadProvider.h" + +#if ENABLE(GAMEPAD) + +#include "GamepadData.h" +#include "UIGamepad.h" +#include "WebProcessPool.h" +#include <WebCore/MockGamepadProvider.h> +#include <WebCore/PlatformGamepad.h> +#include <wtf/NeverDestroyed.h> + +using namespace WebCore; + +namespace WebKit { + +static const double maximumGamepadUpdateInterval = 1 / 120.0; + +UIGamepadProvider& UIGamepadProvider::singleton() +{ + static NeverDestroyed<UIGamepadProvider> sharedProvider; + return sharedProvider; +} + +UIGamepadProvider::UIGamepadProvider() + : m_gamepadSyncTimer(RunLoop::main(), this, &UIGamepadProvider::gamepadSyncTimerFired) +{ + platformSetDefaultGamepadProvider(); +} + +UIGamepadProvider::~UIGamepadProvider() +{ + if (!m_processPoolsUsingGamepads.isEmpty()) + GamepadProvider::singleton().stopMonitoringGamepads(*this); +} + +void UIGamepadProvider::gamepadSyncTimerFired() +{ + auto webPageProxy = platformWebPageProxyForGamepadInput(); + if (!webPageProxy || !m_processPoolsUsingGamepads.contains(&webPageProxy->process().processPool())) + return; + + webPageProxy->gamepadActivity(snapshotGamepads(), m_shouldMakeGamepadsVisibleOnSync); + m_shouldMakeGamepadsVisibleOnSync = false; +} + +void UIGamepadProvider::scheduleGamepadStateSync() +{ + if (!m_isMonitoringGamepads || m_gamepadSyncTimer.isActive()) + return; + + if (m_gamepads.isEmpty() || m_processPoolsUsingGamepads.isEmpty()) { + m_gamepadSyncTimer.stop(); + return; + } + + m_gamepadSyncTimer.startOneShot(maximumGamepadUpdateInterval); +} + +void UIGamepadProvider::setInitialConnectedGamepads(const Vector<PlatformGamepad*>& initialGamepads) +{ + ASSERT(!m_hasInitialGamepads); + + m_gamepads.resize(initialGamepads.size()); + + for (auto* gamepad : initialGamepads) { + if (!gamepad) + continue; + m_gamepads[gamepad->index()] = std::make_unique<UIGamepad>(*gamepad); + } + + for (auto& pool : m_processPoolsUsingGamepads) + pool->setInitialConnectedGamepads(m_gamepads); + + m_hasInitialGamepads = true; +} + +void UIGamepadProvider::platformGamepadConnected(PlatformGamepad& gamepad) +{ + if (m_gamepads.size() <= gamepad.index()) + m_gamepads.resize(gamepad.index() + 1); + + ASSERT(!m_gamepads[gamepad.index()]); + m_gamepads[gamepad.index()] = std::make_unique<UIGamepad>(gamepad); + + scheduleGamepadStateSync(); + + for (auto& pool : m_processPoolsUsingGamepads) + pool->gamepadConnected(*m_gamepads[gamepad.index()]); +} + +void UIGamepadProvider::platformGamepadDisconnected(PlatformGamepad& gamepad) +{ + ASSERT(gamepad.index() < m_gamepads.size()); + ASSERT(m_gamepads[gamepad.index()]); + + std::unique_ptr<UIGamepad> disconnectedGamepad = WTFMove(m_gamepads[gamepad.index()]); + + scheduleGamepadStateSync(); + + for (auto& pool : m_processPoolsUsingGamepads) + pool->gamepadDisconnected(*disconnectedGamepad); +} + +void UIGamepadProvider::platformGamepadInputActivity(bool shouldMakeGamepadsVisible) +{ + auto platformGamepads = GamepadProvider::singleton().platformGamepads(); + ASSERT(platformGamepads.size() == m_gamepads.size()); + + for (size_t i = 0; i < platformGamepads.size(); ++i) { + if (!platformGamepads[i]) { + ASSERT(!m_gamepads[i]); + continue; + } + + ASSERT(m_gamepads[i]); + m_gamepads[i]->updateFromPlatformGamepad(*platformGamepads[i]); + } + + if (shouldMakeGamepadsVisible) + m_shouldMakeGamepadsVisibleOnSync = true; + + scheduleGamepadStateSync(); +} + +void UIGamepadProvider::processPoolStartedUsingGamepads(WebProcessPool& pool) +{ + ASSERT(!m_processPoolsUsingGamepads.contains(&pool)); + m_processPoolsUsingGamepads.add(&pool); + + if (!m_isMonitoringGamepads && platformWebPageProxyForGamepadInput()) + startMonitoringGamepads(); +} + +void UIGamepadProvider::processPoolStoppedUsingGamepads(WebProcessPool& pool) +{ + ASSERT(m_processPoolsUsingGamepads.contains(&pool)); + m_processPoolsUsingGamepads.remove(&pool); + + if (m_isMonitoringGamepads && !platformWebPageProxyForGamepadInput()) + platformStopMonitoringInput(); +} + +void UIGamepadProvider::viewBecameActive(WebPageProxy& page) +{ + if (!m_processPoolsUsingGamepads.contains(&page.process().processPool())) + return; + + if (!m_isMonitoringGamepads) + startMonitoringGamepads(); + + if (platformWebPageProxyForGamepadInput()) + platformStartMonitoringInput(); +} + +void UIGamepadProvider::viewBecameInactive(WebPageProxy& page) +{ + auto pageForGamepadInput = platformWebPageProxyForGamepadInput(); + if (pageForGamepadInput == &page) + platformStopMonitoringInput(); +} + +void UIGamepadProvider::startMonitoringGamepads() +{ + if (m_isMonitoringGamepads) + return; + + m_isMonitoringGamepads = true; + ASSERT(!m_processPoolsUsingGamepads.isEmpty()); + GamepadProvider::singleton().startMonitoringGamepads(*this); +} + +void UIGamepadProvider::stopMonitoringGamepads() +{ + if (!m_isMonitoringGamepads) + return; + + m_isMonitoringGamepads = false; + + ASSERT(m_processPoolsUsingGamepads.isEmpty()); + GamepadProvider::singleton().stopMonitoringGamepads(*this); + + m_gamepads.clear(); +} + +Vector<GamepadData> UIGamepadProvider::snapshotGamepads() +{ + Vector<GamepadData> gamepadDatas; + gamepadDatas.reserveInitialCapacity(m_gamepads.size()); + + for (auto& gamepad : m_gamepads) { + if (gamepad) + gamepadDatas.uncheckedAppend(gamepad->condensedGamepadData()); + else + gamepadDatas.uncheckedAppend({ }); + } + + return gamepadDatas; +} + +#if !PLATFORM(COCOA) + +void UIGamepadProvider::platformSetDefaultGamepadProvider() +{ + // FIXME: Implement for other platforms +} + +WebPageProxy* UIGamepadProvider::platformWebPageProxyForGamepadInput() +{ + // FIXME: Implement for other platforms + return nullptr; +} + +void UIGamepadProvider::platformStopMonitoringInput() +{ +} + +void UIGamepadProvider::platformStartMonitoringInput() +{ +} + +#endif // !PLATFORM(MAC) + +} + +#endif // ENABLE(GAMEPAD) diff --git a/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h b/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h new file mode 100644 index 000000000..e076c2f33 --- /dev/null +++ b/Source/WebKit2/UIProcess/Gamepad/UIGamepadProvider.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2016 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if ENABLE(GAMEPAD) + +#include <WebCore/GamepadProviderClient.h> +#include <wtf/HashSet.h> +#include <wtf/NeverDestroyed.h> +#include <wtf/RunLoop.h> +#include <wtf/Vector.h> + +namespace WebKit { + +class UIGamepad; +class WebPageProxy; +class WebProcessPool; +class GamepadData; + +class UIGamepadProvider : public WebCore::GamepadProviderClient { +public: + static UIGamepadProvider& singleton(); + + void processPoolStartedUsingGamepads(WebProcessPool&); + void processPoolStoppedUsingGamepads(WebProcessPool&); + + void viewBecameActive(WebPageProxy&); + void viewBecameInactive(WebPageProxy&); + + Vector<GamepadData> gamepadStates() const; + +#if PLATFORM(COCOA) + static void setUsesGameControllerFramework(); +#endif + + Vector<GamepadData> snapshotGamepads(); + +private: + friend NeverDestroyed<UIGamepadProvider>; + UIGamepadProvider(); + ~UIGamepadProvider() final; + + void startMonitoringGamepads(); + void stopMonitoringGamepads(); + + void platformSetDefaultGamepadProvider(); + WebPageProxy* platformWebPageProxyForGamepadInput(); + void platformStopMonitoringInput(); + void platformStartMonitoringInput(); + + void setInitialConnectedGamepads(const Vector<WebCore::PlatformGamepad*>&) final; + void platformGamepadConnected(WebCore::PlatformGamepad&) final; + void platformGamepadDisconnected(WebCore::PlatformGamepad&) final; + void platformGamepadInputActivity(bool shouldMakeGamepadsVisible) final; + + void scheduleGamepadStateSync(); + void gamepadSyncTimerFired(); + + HashSet<WebProcessPool*> m_processPoolsUsingGamepads; + + Vector<std::unique_ptr<UIGamepad>> m_gamepads; + + RunLoop::Timer<UIGamepadProvider> m_gamepadSyncTimer; + + bool m_isMonitoringGamepads { false }; + bool m_hasInitialGamepads { false }; + bool m_shouldMakeGamepadsVisibleOnSync { false }; +}; + +} + +#endif // ENABLE(GAMEPAD) |