mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Auto merge of #23904 - paulrouget:loop2, r=gterzian
Better Hololens loop Depends on #23900 Fix #23823 r? @gterzian <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23904) <!-- Reviewable:end -->
This commit is contained in:
commit
371f514664
4 changed files with 165 additions and 58 deletions
|
@ -490,7 +490,8 @@ impl ServoGlue {
|
||||||
.host_callbacks
|
.host_callbacks
|
||||||
.on_allow_navigation(url.to_string());
|
.on_allow_navigation(url.to_string());
|
||||||
let window_event = WindowEvent::AllowNavigationResponse(pipeline_id, data);
|
let window_event = WindowEvent::AllowNavigationResponse(pipeline_id, data);
|
||||||
let _ = self.process_event(window_event);
|
self.events.push(window_event);
|
||||||
|
let _ = self.perform_updates();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
EmbedderMsg::HistoryChanged(entries, current) => {
|
EmbedderMsg::HistoryChanged(entries, current) => {
|
||||||
|
|
115
support/hololens/.clang-format
Normal file
115
support/hololens/.clang-format
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
BasedOnStyle: Mozilla
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: false
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: false
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
RawStringFormats:
|
||||||
|
- Delimiter: pb
|
||||||
|
Language: TextProto
|
||||||
|
BasedOnStyle: google
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: false
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Cpp11
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
|
@ -22,6 +22,8 @@ namespace winrt::ServoApp::implementation {
|
||||||
BrowserPage::BrowserPage() {
|
BrowserPage::BrowserPage() {
|
||||||
log("BrowserPage::BrowserPage()");
|
log("BrowserPage::BrowserPage()");
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
InitializeConditionVariable(&mGLCondVar);
|
||||||
|
InitializeCriticalSection(&mGLLock);
|
||||||
Loaded(std::bind(&BrowserPage::OnPageLoaded, this, _1, _2));
|
Loaded(std::bind(&BrowserPage::OnPageLoaded, this, _1, _2));
|
||||||
Window::Current().CoreWindow().VisibilityChanged(
|
Window::Current().CoreWindow().VisibilityChanged(
|
||||||
std::bind(&BrowserPage::OnVisibilityChanged, this, _1, _2));
|
std::bind(&BrowserPage::OnVisibilityChanged, this, _1, _2));
|
||||||
|
@ -31,15 +33,13 @@ void BrowserPage::Shutdown() {
|
||||||
log("BrowserPage::Shutdown()");
|
log("BrowserPage::Shutdown()");
|
||||||
|
|
||||||
if (mServo != nullptr) {
|
if (mServo != nullptr) {
|
||||||
if (!IsLoopRunning()) {
|
if (!mLooping) {
|
||||||
// FIXME: this should not happen. In that case, we can't send the
|
// FIXME: this should not happen. In that case, we can't send the
|
||||||
// shutdown event to Servo.
|
// shutdown event to Servo.
|
||||||
} else {
|
} else {
|
||||||
HANDLE hEvent = ::CreateEventA(nullptr, FALSE, FALSE, sShutdownEvent);
|
RunOnGLThread([=] { mServo->RequestShutdown(); });
|
||||||
RunOnGLThread([=] {mServo->RequestShutdown();});
|
mLoopTask->wait();
|
||||||
log("Waiting for Servo to shutdown");
|
mLoopTask.reset();
|
||||||
::WaitForSingleObject(hEvent, INFINITE);
|
|
||||||
StopRenderLoop();
|
|
||||||
mServo.reset();
|
mServo.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,10 +63,10 @@ void BrowserPage::OnVisibilityChanged(CoreWindow const &,
|
||||||
// stopping the event loop, which we can't recover from yet (see comment in
|
// stopping the event loop, which we can't recover from yet (see comment in
|
||||||
// Loop())
|
// Loop())
|
||||||
|
|
||||||
// if (visible && !IsLoopRunning()) {
|
// if (visible && !mLooping) {
|
||||||
// StartRenderLoop();
|
// StartRenderLoop();
|
||||||
//}
|
//}
|
||||||
// if (!visible && IsLoopRunning()) {
|
// if (!visible && mLooping) {
|
||||||
// StopRenderLoop();
|
// StopRenderLoop();
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
@ -92,15 +92,9 @@ void BrowserPage::RecoverFromLostDevice() {
|
||||||
|
|
||||||
/**** GL THREAD LOOP ****/
|
/**** GL THREAD LOOP ****/
|
||||||
|
|
||||||
bool BrowserPage::IsLoopRunning() {
|
void BrowserPage::Loop() {
|
||||||
return mLoopTask != nullptr && !mLoopTask->is_done();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowserPage::Loop(cancellation_token cancel) {
|
|
||||||
log("BrowserPage::Loop(). GL thread: %i", GetCurrentThreadId());
|
log("BrowserPage::Loop(). GL thread: %i", GetCurrentThreadId());
|
||||||
|
|
||||||
HANDLE hEvent = ::CreateEventA(nullptr, FALSE, FALSE, sWakeupEvent);
|
|
||||||
|
|
||||||
mOpenGLES.MakeCurrent(mRenderSurface);
|
mOpenGLES.MakeCurrent(mRenderSurface);
|
||||||
|
|
||||||
EGLint panelWidth = 0;
|
EGLint panelWidth = 0;
|
||||||
|
@ -118,51 +112,48 @@ void BrowserPage::Loop(cancellation_token cancel) {
|
||||||
throw winrt::hresult_error(E_FAIL, L"Recovering loop unimplemented");
|
throw winrt::hresult_error(E_FAIL, L"Recovering loop unimplemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
// mServo->SetBatchMode(true);
|
mServo->SetBatchMode(true);
|
||||||
// FIXME: ^ this should be necessary as we call perform_update
|
|
||||||
// ourself. But enabling batch mode will make clicking a link
|
|
||||||
// not working because during the click, this thread is not
|
|
||||||
// waiting on the hEvent object. See the "wakeup" comment.
|
|
||||||
|
|
||||||
log("Entering loop");
|
while (true) {
|
||||||
while (!cancel.is_canceled()) {
|
EnterCriticalSection(&mGLLock);
|
||||||
// Block until wakeup is called.
|
while (mTasks.size() == 0 && !mAnimating && mLooping) {
|
||||||
// Or run full speed if animating (see OnAnimatingChanged),
|
SleepConditionVariableCS(&mGLCondVar, &mGLLock, INFINITE);
|
||||||
// it will endup blocking on Flush to limit rendering to 60FPS
|
}
|
||||||
if (!mAnimating) {
|
if (!mLooping) {
|
||||||
::WaitForSingleObject(hEvent, INFINITE);
|
LeaveCriticalSection(&mGLLock);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mTasksMutex.lock();
|
|
||||||
for (auto &&task : mTasks) {
|
for (auto &&task : mTasks) {
|
||||||
task();
|
task();
|
||||||
}
|
}
|
||||||
mTasks.clear();
|
mTasks.clear();
|
||||||
mTasksMutex.unlock();
|
LeaveCriticalSection(&mGLLock);
|
||||||
mServo->PerformUpdates();
|
mServo->PerformUpdates();
|
||||||
}
|
}
|
||||||
log("Leaving loop");
|
|
||||||
mServo->DeInit();
|
mServo->DeInit();
|
||||||
cancel_current_task();
|
cancel_current_task();
|
||||||
} // namespace winrt::ServoApp::implementation
|
} // namespace winrt::ServoApp::implementation
|
||||||
|
|
||||||
void BrowserPage::StartRenderLoop() {
|
void BrowserPage::StartRenderLoop() {
|
||||||
if (IsLoopRunning()) {
|
if (mLooping) {
|
||||||
#if defined _DEBUG
|
#if defined _DEBUG
|
||||||
throw winrt::hresult_error(E_FAIL, L"GL thread is already looping");
|
throw winrt::hresult_error(E_FAIL, L"GL thread is already looping");
|
||||||
#else
|
#else
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
mLooping = true;
|
||||||
log("BrowserPage::StartRenderLoop(). UI thread: %i", GetCurrentThreadId());
|
log("BrowserPage::StartRenderLoop(). UI thread: %i", GetCurrentThreadId());
|
||||||
auto token = mLoopCancel.get_token();
|
auto task = Concurrency::create_task([=] { Loop(); });
|
||||||
mLoopTask = std::make_unique<Concurrency::task<void>>(
|
mLoopTask = std::make_unique<Concurrency::task<void>>(task);
|
||||||
Concurrency::create_task([=] { Loop(token); }, token));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserPage::StopRenderLoop() {
|
void BrowserPage::StopRenderLoop() {
|
||||||
if (IsLoopRunning()) {
|
if (mLooping) {
|
||||||
mLoopCancel.cancel();
|
EnterCriticalSection(&mGLLock);
|
||||||
WakeUp();
|
mLooping = false;
|
||||||
|
LeaveCriticalSection(&mGLLock);
|
||||||
|
WakeConditionVariable(&mGLCondVar);
|
||||||
mLoopTask->wait();
|
mLoopTask->wait();
|
||||||
mLoopTask.reset();
|
mLoopTask.reset();
|
||||||
}
|
}
|
||||||
|
@ -192,9 +183,9 @@ void BrowserPage::OnHistoryChanged(bool back, bool forward) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserPage::OnShutdownComplete() {
|
void BrowserPage::OnShutdownComplete() {
|
||||||
log("Servo notified ShutdownComplete");
|
EnterCriticalSection(&mGLLock);
|
||||||
HANDLE hEvent = ::OpenEventA(EVENT_ALL_ACCESS, FALSE, sShutdownEvent);
|
mLooping = false;
|
||||||
::SetEvent(hEvent);
|
LeaveCriticalSection(&mGLLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserPage::OnAlert(std::wstring message) {
|
void BrowserPage::OnAlert(std::wstring message) {
|
||||||
|
@ -225,15 +216,17 @@ void BrowserPage::Flush() {
|
||||||
void BrowserPage::MakeCurrent() { mOpenGLES.MakeCurrent(mRenderSurface); }
|
void BrowserPage::MakeCurrent() { mOpenGLES.MakeCurrent(mRenderSurface); }
|
||||||
|
|
||||||
void BrowserPage::WakeUp() {
|
void BrowserPage::WakeUp() {
|
||||||
// FIXME: this won't work if it's triggered while the thread is not
|
RunOnGLThread([=] { });
|
||||||
// waiting. We need a better looping logic.
|
|
||||||
HANDLE hEvent = ::OpenEventA(EVENT_ALL_ACCESS, FALSE, sWakeupEvent);
|
|
||||||
::SetEvent(hEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrowserPage::OnAllowNavigation(std::wstring) { return true; }
|
bool BrowserPage::OnAllowNavigation(std::wstring) { return true; }
|
||||||
|
|
||||||
void BrowserPage::OnAnimatingChanged(bool animating) { mAnimating = animating; }
|
void BrowserPage::OnAnimatingChanged(bool animating) {
|
||||||
|
EnterCriticalSection(&mGLLock);
|
||||||
|
mAnimating = animating;
|
||||||
|
LeaveCriticalSection(&mGLLock);
|
||||||
|
WakeConditionVariable(&mGLCondVar);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Callable> void BrowserPage::RunOnUIThread(Callable cb) {
|
template <typename Callable> void BrowserPage::RunOnUIThread(Callable cb) {
|
||||||
swapChainPanel().Dispatcher().RunAsync(
|
swapChainPanel().Dispatcher().RunAsync(
|
||||||
|
@ -300,10 +293,10 @@ void BrowserPage::OnSurfaceClicked(IInspectable const &,
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowserPage::RunOnGLThread(std::function<void()> task) {
|
void BrowserPage::RunOnGLThread(std::function<void()> task) {
|
||||||
mTasksMutex.lock();
|
EnterCriticalSection(&mGLLock);
|
||||||
mTasks.push_back(task);
|
mTasks.push_back(task);
|
||||||
mTasksMutex.unlock();
|
LeaveCriticalSection(&mGLLock);
|
||||||
WakeUp();
|
WakeConditionVariable(&mGLCondVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace winrt::ServoApp::implementation
|
} // namespace winrt::ServoApp::implementation
|
||||||
|
|
|
@ -11,9 +11,6 @@
|
||||||
|
|
||||||
namespace winrt::ServoApp::implementation {
|
namespace winrt::ServoApp::implementation {
|
||||||
|
|
||||||
static char sWakeupEvent[] = "SIGNAL_WAKEUP";
|
|
||||||
static char sShutdownEvent[] = "SIGNAL_SHUTDOWN";
|
|
||||||
|
|
||||||
struct BrowserPage : BrowserPageT<BrowserPage>,
|
struct BrowserPage : BrowserPageT<BrowserPage>,
|
||||||
public servo::ServoDelegate {
|
public servo::ServoDelegate {
|
||||||
public:
|
public:
|
||||||
|
@ -66,21 +63,22 @@ private:
|
||||||
|
|
||||||
void StartRenderLoop();
|
void StartRenderLoop();
|
||||||
void StopRenderLoop();
|
void StopRenderLoop();
|
||||||
void Loop(Concurrency::cancellation_token);
|
void Loop();
|
||||||
bool IsLoopRunning();
|
|
||||||
|
|
||||||
Concurrency::cancellation_token_source mLoopCancel;
|
|
||||||
std::unique_ptr<Concurrency::task<void>> mLoopTask;
|
std::unique_ptr<Concurrency::task<void>> mLoopTask;
|
||||||
winrt::ServoApp::ImmersiveViewSource mImmersiveViewSource;
|
winrt::ServoApp::ImmersiveViewSource mImmersiveViewSource;
|
||||||
EGLSurface mRenderSurface{EGL_NO_SURFACE};
|
EGLSurface mRenderSurface{EGL_NO_SURFACE};
|
||||||
std::unique_ptr<servo::Servo> mServo;
|
std::unique_ptr<servo::Servo> mServo;
|
||||||
|
|
||||||
std::vector<std::function<void()>> mTasks;
|
std::vector<std::function<void()>> mTasks;
|
||||||
std::mutex mTasksMutex;
|
|
||||||
|
CRITICAL_SECTION mGLLock;
|
||||||
|
CONDITION_VARIABLE mGLCondVar;
|
||||||
|
|
||||||
|
bool mAnimating = false;
|
||||||
|
bool mLooping = false;
|
||||||
|
|
||||||
OpenGLES mOpenGLES; // FIXME: shared pointer
|
OpenGLES mOpenGLES; // FIXME: shared pointer
|
||||||
|
|
||||||
bool mAnimating;
|
|
||||||
};
|
};
|
||||||
} // namespace winrt::ServoApp::implementation
|
} // namespace winrt::ServoApp::implementation
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue