diff options
Diffstat (limited to 'support/hololens/ServoApp/BrowserPage.cpp')
-rw-r--r-- | support/hololens/ServoApp/BrowserPage.cpp | 267 |
1 files changed, 29 insertions, 238 deletions
diff --git a/support/hololens/ServoApp/BrowserPage.cpp b/support/hololens/ServoApp/BrowserPage.cpp index 62b3b3a9a72..0233308fa75 100644 --- a/support/hololens/ServoApp/BrowserPage.cpp +++ b/support/hololens/ServoApp/BrowserPage.cpp @@ -7,261 +7,78 @@ #include "BrowserPage.h" #include "BrowserPage.g.cpp" #include "ImmersiveView.h" -#include "OpenGLES.h" -using namespace std::placeholders; using namespace winrt::Windows::UI::Xaml; using namespace winrt::Windows::UI::Core; using namespace winrt::Windows::UI::ViewManagement; -using namespace winrt::Windows::Foundation; using namespace winrt::Windows::Graphics::Holographic; -using namespace concurrency; -using namespace servo; +using namespace winrt::Windows::ApplicationModel::Core; namespace winrt::ServoApp::implementation { BrowserPage::BrowserPage() { - log("BrowserPage::BrowserPage()"); InitializeComponent(); - InitializeConditionVariable(&mGLCondVar); - InitializeCriticalSection(&mGLLock); - Loaded(std::bind(&BrowserPage::OnPageLoaded, this, _1, _2)); - Window::Current().CoreWindow().VisibilityChanged( - std::bind(&BrowserPage::OnVisibilityChanged, this, _1, _2)); + BindServoEvents(); } -void BrowserPage::Shutdown() { - log("BrowserPage::Shutdown()"); - - if (mServo != nullptr) { - if (!mLooping) { - // FIXME: this should not happen. In that case, we can't send the - // shutdown event to Servo. - } else { - RunOnGLThread([=] { mServo->RequestShutdown(); }); - mLoopTask->wait(); - mLoopTask.reset(); - mServo.reset(); - } - } -} - -void BrowserPage::OnPageLoaded(IInspectable const &, RoutedEventArgs const &) { - log("BrowserPage::OnPageLoaded()"); - CreateRenderSurface(); - StartRenderLoop(); - swapChainPanel().PointerReleased( - std::bind(&BrowserPage::OnSurfaceClicked, this, _1, _2)); - swapChainPanel().ManipulationDelta( - std::bind(&BrowserPage::OnSurfaceManipulationDelta, this, _1, _2)); -} - -void BrowserPage::OnVisibilityChanged(CoreWindow const &, - VisibilityChangedEventArgs const &args) { - auto visible = args.Visible(); - - // FIXME: for now, this is disabled as we get this message before shutdown, - // stopping the event loop, which we can't recover from yet (see comment in - // Loop()) - - // if (visible && !mLooping) { - // StartRenderLoop(); - //} - // if (!visible && mLooping) { - // StopRenderLoop(); - //} -} - -void BrowserPage::CreateRenderSurface() { - if (mRenderSurface == EGL_NO_SURFACE) { - mRenderSurface = mOpenGLES.CreateSurface(swapChainPanel()); - } -} - -void BrowserPage::DestroyRenderSurface() { - mOpenGLES.DestroySurface(mRenderSurface); - mRenderSurface = EGL_NO_SURFACE; -} - -void BrowserPage::RecoverFromLostDevice() { - StopRenderLoop(); - DestroyRenderSurface(); - mOpenGLES.Reset(); - CreateRenderSurface(); - StartRenderLoop(); -} - -/**** GL THREAD LOOP ****/ - -void BrowserPage::Loop() { - log("BrowserPage::Loop(). GL thread: %i", GetCurrentThreadId()); - - mOpenGLES.MakeCurrent(mRenderSurface); - - EGLint panelWidth = 0; - EGLint panelHeight = 0; - mOpenGLES.GetSurfaceDimensions(mRenderSurface, &panelWidth, &panelHeight); - glViewport(0, 0, panelWidth, panelHeight); - - if (mServo == nullptr) { - log("Entering loop"); - ServoDelegate *sd = static_cast<ServoDelegate *>(this); - mServo = std::make_unique<Servo>(panelWidth, panelHeight, *sd); - } else { - // FIXME: this will fail since create_task didn't pick the thread - // where Servo was running initially. - throw winrt::hresult_error(E_FAIL, L"Recovering loop unimplemented"); - } - - mServo->SetBatchMode(true); - - while (true) { - EnterCriticalSection(&mGLLock); - while (mTasks.size() == 0 && !mAnimating && mLooping) { - SleepConditionVariableCS(&mGLCondVar, &mGLLock, INFINITE); - } - if (!mLooping) { - LeaveCriticalSection(&mGLLock); - break; - } - for (auto &&task : mTasks) { - task(); - } - mTasks.clear(); - LeaveCriticalSection(&mGLLock); - mServo->PerformUpdates(); - } - mServo->DeInit(); - cancel_current_task(); -} // namespace winrt::ServoApp::implementation - -void BrowserPage::StartRenderLoop() { - if (mLooping) { -#if defined _DEBUG - throw winrt::hresult_error(E_FAIL, L"GL thread is already looping"); -#else - return; -#endif - } - mLooping = true; - log("BrowserPage::StartRenderLoop(). UI thread: %i", GetCurrentThreadId()); - auto task = Concurrency::create_task([=] { Loop(); }); - mLoopTask = std::make_unique<Concurrency::task<void>>(task); -} - -void BrowserPage::StopRenderLoop() { - if (mLooping) { - EnterCriticalSection(&mGLLock); - mLooping = false; - LeaveCriticalSection(&mGLLock); - WakeConditionVariable(&mGLCondVar); - mLoopTask->wait(); - mLoopTask.reset(); - } -} - -/**** SERVO CALLBACKS ****/ - -void BrowserPage::OnLoadStarted() { - RunOnUIThread([=] { +void BrowserPage::BindServoEvents() { + servoControl().OnURLChanged( + [=](const auto &, hstring url) { urlTextbox().Text(url); }); + servoControl().OnTitleChanged([=](const auto &, hstring title) {}); + servoControl().OnHistoryChanged([=](bool back, bool forward) { + backButton().IsEnabled(back); + forwardButton().IsEnabled(forward); + }); + servoControl().OnLoadStarted([=] { reloadButton().IsEnabled(false); stopButton().IsEnabled(true); }); -} - -void BrowserPage::OnLoadEnded() { - RunOnUIThread([=] { + servoControl().OnLoadEnded([=] { reloadButton().IsEnabled(true); stopButton().IsEnabled(false); }); } -void BrowserPage::OnHistoryChanged(bool back, bool forward) { - RunOnUIThread([=] { - backButton().IsEnabled(back); - forwardButton().IsEnabled(forward); - }); -} - -void BrowserPage::OnShutdownComplete() { - EnterCriticalSection(&mGLLock); - mLooping = false; - LeaveCriticalSection(&mGLLock); -} - -void BrowserPage::OnAlert(std::wstring message) { - // FIXME: make this sync - RunOnUIThread([=] { - Windows::UI::Popups::MessageDialog msg{message}; - msg.ShowAsync(); - }); -} - -void BrowserPage::OnTitleChanged(std::wstring title) { - RunOnUIThread([=] { ApplicationView::GetForCurrentView().Title(title); }); -} - -void BrowserPage::OnURLChanged(std::wstring url) { - RunOnUIThread([=] { urlTextbox().Text(url); }); -} - -void BrowserPage::Flush() { - if (mOpenGLES.SwapBuffers(mRenderSurface) != GL_TRUE) { - // The call to eglSwapBuffers might not be successful (i.e. due to Device - // Lost) If the call fails, then we must reinitialize EGL and the GL - // resources. - RunOnUIThread([=] { RecoverFromLostDevice(); }); - } -} - -void BrowserPage::MakeCurrent() { mOpenGLES.MakeCurrent(mRenderSurface); } - -void BrowserPage::WakeUp() { - RunOnGLThread([=] { }); -} - -bool BrowserPage::OnAllowNavigation(std::wstring) { return true; } - -void BrowserPage::OnAnimatingChanged(bool animating) { - EnterCriticalSection(&mGLLock); - mAnimating = animating; - LeaveCriticalSection(&mGLLock); - WakeConditionVariable(&mGLCondVar); -} - -template <typename Callable> void BrowserPage::RunOnUIThread(Callable cb) { - swapChainPanel().Dispatcher().RunAsync( - Windows::UI::Core::CoreDispatcherPriority::High, cb); +void BrowserPage::Shutdown() { + servoControl().Shutdown(); } /**** USER INTERACTIONS WITH UI ****/ void BrowserPage::OnBackButtonClicked(IInspectable const &, RoutedEventArgs const &) { - RunOnGLThread([=] { mServo->GoBack(); }); + servoControl().GoBack(); } void BrowserPage::OnForwardButtonClicked(IInspectable const &, RoutedEventArgs const &) { - RunOnGLThread([=] { mServo->GoForward(); }); + servoControl().GoForward(); } void BrowserPage::OnReloadButtonClicked(IInspectable const &, RoutedEventArgs const &) { - RunOnGLThread([=] { mServo->Reload(); }); + servoControl().Reload(); } void BrowserPage::OnStopButtonClicked(IInspectable const &, RoutedEventArgs const &) { - RunOnGLThread([=] { mServo->Stop(); }); + servoControl().Stop(); +} + +void BrowserPage::OnURLEdited(IInspectable const &sender, + Input::KeyRoutedEventArgs const &e) { + if (e.Key() == Windows::System::VirtualKey::Enter) { + servoControl().Focus(FocusState::Programmatic); + auto input = urlTextbox().Text(); + auto uri = servoControl().LoadURIOrSearch(input); + urlTextbox().Text(uri.ToString()); + } } void BrowserPage::OnImmersiveButtonClicked(IInspectable const &, RoutedEventArgs const &) { if (HolographicSpace::IsAvailable()) { log("Holographic space available"); - auto v = - winrt::Windows::ApplicationModel::Core::CoreApplication::CreateNewView( - mImmersiveViewSource); + auto v = CoreApplication::CreateNewView(mImmersiveViewSource); auto parentId = ApplicationView::GetForCurrentView().Id(); v.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, [=] { auto winId = ApplicationView::GetForCurrentView().Id(); @@ -273,30 +90,4 @@ void BrowserPage::OnImmersiveButtonClicked(IInspectable const &, } } -void BrowserPage::OnSurfaceManipulationDelta( - IInspectable const &, Input::ManipulationDeltaRoutedEventArgs const &e) { - auto x = e.Position().X; - auto y = e.Position().Y; - auto dx = e.Delta().Translation.X; - auto dy = e.Delta().Translation.Y; - RunOnGLThread([=] { mServo->Scroll(dx, dy, x, y); }); - e.Handled(true); -} - -void BrowserPage::OnSurfaceClicked(IInspectable const &, - Input::PointerRoutedEventArgs const &e) { - auto coords = e.GetCurrentPoint(swapChainPanel()); - auto x = coords.Position().X; - auto y = coords.Position().Y; - RunOnGLThread([=] { mServo->Click(x, y); }); - e.Handled(true); -} - -void BrowserPage::RunOnGLThread(std::function<void()> task) { - EnterCriticalSection(&mGLLock); - mTasks.push_back(task); - LeaveCriticalSection(&mGLLock); - WakeConditionVariable(&mGLCondVar); -} - } // namespace winrt::ServoApp::implementation |