Global Metrics
path: .metrics.cyclomatic.sum
old: 121.0
new: 25.0
path: .metrics.cyclomatic.average
old: 2.1607142857142856
new: 1.6666666666666667
path: .metrics.mi.mi_sei
old: -66.52767086372864
new: -0.25675347532985526
path: .metrics.mi.mi_original
old: -16.582158762728383
new: 34.29280974268012
path: .metrics.mi.mi_visual_studio
old: 0.0
new: 20.054274703321703
path: .metrics.loc.ploc
old: 577.0
new: 151.0
path: .metrics.loc.blank
old: 111.0
new: 40.0
path: .metrics.loc.cloc
old: 57.0
new: 21.0
path: .metrics.loc.sloc
old: 745.0
new: 212.0
path: .metrics.loc.lloc
old: 184.0
new: 68.0
path: .metrics.cognitive.sum
old: 86.0
new: 12.0
path: .metrics.cognitive.average
old: 1.6862745098039216
new: 0.8571428571428571
path: .metrics.nargs.sum
old: 112.0
new: 3.0
path: .metrics.nargs.average
old: 2.196078431372549
new: 0.21428571428571427
path: .metrics.nexits.average
old: 1.3725490196078431
new: 0.7142857142857143
path: .metrics.nexits.sum
old: 70.0
new: 10.0
path: .metrics.halstead.estimated_program_length
old: 1929.7836052918128
new: 841.5415307421127
path: .metrics.halstead.N2
old: 1270.0
new: 286.0
path: .metrics.halstead.length
old: 3097.0
new: 694.0
path: .metrics.halstead.volume
old: 24793.419228853443
new: 4896.366010237825
path: .metrics.halstead.bugs
old: 5.15822811283093
new: 1.0561459852936046
path: .metrics.halstead.N1
old: 1827.0
new: 408.0
path: .metrics.halstead.vocabulary
old: 257.0
new: 133.0
path: .metrics.halstead.time
old: 106944.92816327373
new: 9908.21235090579
path: .metrics.halstead.n1
old: 28.0
new: 27.0
path: .metrics.halstead.difficulty
old: 77.64192139737992
new: 36.424528301886795
path: .metrics.halstead.level
old: 0.012879640044994376
new: 0.027454027454027453
path: .metrics.halstead.n2
old: 229.0
new: 106.0
path: .metrics.halstead.purity_ratio
old: 0.6231138538236399
new: 1.2125958656226408
path: .metrics.halstead.effort
old: 1925008.7069389268
new: 178347.8223163042
path: .metrics.nom.closures
old: 0.0
new: 2.0
path: .metrics.nom.total
old: 51.0
new: 14.0
path: .metrics.nom.functions
old: 51.0
new: 12.0
Spaces Data
Minimal test - lines (19, 212)
path: .spaces[0].metrics.nexits.average
old: 1.0
new: 0.7142857142857143
path: .spaces[0].metrics.nexits.sum
old: 1.0
new: 10.0
path: .spaces[0].metrics.cyclomatic.average
old: 1.0
new: 1.7142857142857142
path: .spaces[0].metrics.cyclomatic.sum
old: 1.0
new: 24.0
path: .spaces[0].metrics.loc.ploc
old: 5.0
new: 141.0
path: .spaces[0].metrics.loc.sloc
old: 6.0
new: 194.0
path: .spaces[0].metrics.loc.blank
old: 0.0
new: 38.0
path: .spaces[0].metrics.loc.cloc
old: 1.0
new: 15.0
path: .spaces[0].metrics.loc.lloc
old: 1.0
new: 68.0
path: .spaces[0].metrics.cognitive.sum
old: 0.0
new: 12.0
path: .spaces[0].metrics.cognitive.average
old: 0.0
new: 0.8571428571428571
path: .spaces[0].metrics.halstead.n1
old: 9.0
new: 27.0
path: .spaces[0].metrics.halstead.estimated_program_length
old: 57.05865002596162
new: 768.573508250565
path: .spaces[0].metrics.halstead.difficulty
old: 6.0
new: 38.41237113402062
path: .spaces[0].metrics.halstead.effort
old: 650.5083002250007
new: 182447.85684596415
path: .spaces[0].metrics.halstead.time
old: 36.13935001250004
new: 10135.992046998008
path: .spaces[0].metrics.halstead.N2
old: 12.0
new: 276.0
path: .spaces[0].metrics.halstead.N1
old: 14.0
new: 407.0
path: .spaces[0].metrics.halstead.length
old: 26.0
new: 683.0
path: .spaces[0].metrics.halstead.volume
old: 108.41805003750012
new: 4749.716079994236
path: .spaces[0].metrics.halstead.level
old: 0.16666666666666666
new: 0.026033279656468063
path: .spaces[0].metrics.halstead.purity_ratio
old: 2.194563462536985
new: 1.1252906416552928
path: .spaces[0].metrics.halstead.bugs
old: 0.02502537766060993
new: 1.0722710714706876
path: .spaces[0].metrics.halstead.n2
old: 9.0
new: 97.0
path: .spaces[0].metrics.halstead.vocabulary
old: 18.0
new: 124.0
path: .spaces[0].metrics.nargs.average
old: 1.0
new: 0.21428571428571427
path: .spaces[0].metrics.nargs.sum
old: 1.0
new: 3.0
path: .spaces[0].metrics.nom.functions
old: 1.0
new: 12.0
path: .spaces[0].metrics.nom.closures
old: 0.0
new: 2.0
path: .spaces[0].metrics.nom.total
old: 1.0
new: 14.0
path: .spaces[0].metrics.mi.mi_visual_studio
old: 68.64112557824586
new: 21.121829933102344
path: .spaces[0].metrics.mi.mi_original
old: 117.37632473880043
new: 36.118329185605006
path: .spaces[0].metrics.mi.mi_sei
old: 123.29556534659632
new: -0.2706894464990661
Code
namespace mozilla {
namespace widget {
static StaticRefPtr sWinCompositorWindowThread;
WinCompositorWindowThread::WinCompositorWindowThread(base::Thread* aThread)
: mThread(aThread) {}
WinCompositorWindowThread::~WinCompositorWindowThread() { delete mThread; }
/* static */
WinCompositorWindowThread* WinCompositorWindowThread::Get() {
return sWinCompositorWindowThread;
}
/* static */
void WinCompositorWindowThread::Start() {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sWinCompositorWindowThread);
base::Thread* thread = new base::Thread("WinCompositor");
base::Thread::Options options;
// HWND requests ui thread.
options.message_loop_type = MessageLoop::TYPE_UI;
if (!thread->StartWithOptions(options)) {
delete thread;
return;
}
sWinCompositorWindowThread = new WinCompositorWindowThread(thread);
}
/* static */
void WinCompositorWindowThread::ShutDown() {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sWinCompositorWindowThread);
layers::SynchronousTask task("WinCompositorWindowThread");
RefPtr runnable = WrapRunnable(
RefPtr(sWinCompositorWindowThread.get()),
&WinCompositorWindowThread::ShutDownTask, &task);
sWinCompositorWindowThread->Loop()->PostTask(runnable.forget());
task.Wait();
sWinCompositorWindowThread = nullptr;
}
void WinCompositorWindowThread::ShutDownTask(layers::SynchronousTask* aTask) {
layers::AutoCompleteTask complete(aTask);
MOZ_ASSERT(IsInCompositorWindowThread());
}
/* static */
MessageLoop* WinCompositorWindowThread::Loop() {
return sWinCompositorWindowThread
? sWinCompositorWindowThread->mThread->message_loop()
: nullptr;
}
/* static */
bool WinCompositorWindowThread::IsInCompositorWindowThread() {
return sWinCompositorWindowThread &&
sWinCompositorWindowThread->mThread->thread_id() ==
PlatformThread::CurrentId();
}
const wchar_t kClassNameCompositorInitalParent[] =
L"MozillaCompositorInitialParentClass";
const wchar_t kClassNameCompositor[] = L"MozillaCompositorWindowClass";
ATOM g_compositor_inital_parent_window_class;
ATOM g_compositor_window_class;
// This runs on the window owner thread.
void InitializeInitialParentWindowClass() {
if (g_compositor_inital_parent_window_class) {
return;
}
WNDCLASSW wc;
wc.style = 0;
wc.lpfnWndProc = ::DefWindowProcW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(nullptr);
wc.hIcon = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = kClassNameCompositorInitalParent;
g_compositor_inital_parent_window_class = ::RegisterClassW(&wc);
}
// This runs on the window owner thread.
void InitializeWindowClass() {
if (g_compositor_window_class) {
return;
}
WNDCLASSW wc;
wc.style = CS_OWNDC;
wc.lpfnWndProc = ::DefWindowProcW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(nullptr);
wc.hIcon = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = kClassNameCompositor;
g_compositor_window_class = ::RegisterClassW(&wc);
}
/* static */
WinCompositorWnds WinCompositorWindowThread::CreateCompositorWindow() {
MOZ_ASSERT(Loop());
if (!Loop()) {
return WinCompositorWnds(nullptr, nullptr);
}
layers::SynchronousTask task("Create compositor window");
HWND initialParentWnd = nullptr;
HWND compositorWnd = nullptr;
RefPtr runnable = NS_NewRunnableFunction(
"WinCompositorWindowThread::CreateCompositorWindow::Runnable", [&]() {
layers::AutoCompleteTask complete(&task);
InitializeInitialParentWindowClass();
InitializeWindowClass();
// Create initial parent window.
// We could not directly create a compositor window with a main window
// as parent window, so instead create it with a temporary placeholder
// parent. Its parent is set as main window in UI process.
initialParentWnd =
::CreateWindowEx(WS_EX_TOOLWINDOW, kClassNameCompositorInitalParent,
nullptr, WS_POPUP | WS_DISABLED, 0, 0, 1, 1,
nullptr, 0, GetModuleHandle(nullptr), 0);
if (!initialParentWnd) {
gfxCriticalNoteOnce << "Inital parent window failed "
<< ::GetLastError();
return;
}
DWORD extendedStyle = WS_EX_NOPARENTNOTIFY | WS_EX_NOREDIRECTIONBITMAP;
if (!StaticPrefs::apz_windows_force_disable_direct_manipulation()) {
extendedStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT;
}
compositorWnd = ::CreateWindowEx(
extendedStyle, kClassNameCompositor, nullptr,
WS_CHILDWINDOW | WS_DISABLED | WS_VISIBLE, 0, 0, 1, 1,
initialParentWnd, 0, GetModuleHandle(nullptr), 0);
if (!compositorWnd) {
gfxCriticalNoteOnce << "Compositor window failed "
<< ::GetLastError();
}
});
Loop()->PostTask(runnable.forget());
task.Wait();
return WinCompositorWnds(compositorWnd, initialParentWnd);
}
/* static */
void WinCompositorWindowThread::DestroyCompositorWindow(
WinCompositorWnds aWnds) {
MOZ_ASSERT(aWnds.mCompositorWnd);
MOZ_ASSERT(aWnds.mInitialParentWnd);
MOZ_ASSERT(Loop());
if (!Loop()) {
return;
}
RefPtr runnable = NS_NewRunnableFunction(
"WinCompositorWidget::CreateNativeWindow::Runnable", [aWnds]() {
::DestroyWindow(aWnds.mCompositorWnd);
::DestroyWindow(aWnds.mInitialParentWnd);
});
Loop()->PostTask(runnable.forget());
}
} // namespace widget
} // namespace mozilla