Bug 1567329 - Append `_AtStartup` to `once` static pref getters. r=erahm
authorNicholas Nethercote <nnethercote@mozilla.com>
Mon, 22 Jul 2019 02:10:14 +0000
changeset 483653 2cb4ffa920c6ad8a4f9b500222dc41d929114646
parent 483652 4d005e8db6cc74dc75eb3337975e69ec33ed87dd
child 483654 14a0bf639210de3d594dd1c147f08337d2ac1d5a
push id113742
push userccoroiu@mozilla.com
push dateMon, 22 Jul 2019 10:08:17 +0000
treeherdermozilla-inbound@3689097a9552 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerserahm
bugs1567329
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1567329 - Append `_AtStartup` to `once` static pref getters. r=erahm Currently it's completely unclear at use sites that the getters for `once` static prefs return the pref value from startup, rather than the current pref value. (Bugs have been caused by this.) This commit improves things by changing the getter name to make it clear that the pref value obtained is from startup. This required changing things within libpref so it distinguishes between the "base id" (`foo_bar`) and the "full id" (`foo_bar` or `foo_bar_DoNotUseDirectly` or `foo_bar_AtStartup` or `foo_bar_AtStartup_DoNotUseDirectly`; the name used depends on the `mirror` and `do_not_use_directly` values in the YAML definition.) The "full id" is used in most places, while the "base id" is used for the `GetPrefName_*` and `GetPrefDefault_*` functions. (This is a nice demonstration of the benefits of the YAML file, BTW. Making this change with the old code would have involved adding an entry to every single pref in StaticPrefList.h.) The patch also rejigs the comment at the top of StaticPrefList.yaml, to clarify some things. Differential Revision: https://phabricator.services.mozilla.com/D38604
dom/media/platforms/wmf/DXVA2Manager.cpp
dom/media/platforms/wmf/WMFDecoderModule.cpp
gfx/2d/HelpersWinFonts.h
gfx/2d/ScaledFontBase.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLLibraryEGL.cpp
gfx/gl/GfxTexturesReporter.cpp
gfx/ipc/GPUChild.cpp
gfx/ipc/GPUParent.cpp
gfx/ipc/GPUProcessHost.cpp
gfx/ipc/GPUProcessManager.cpp
gfx/layers/D3D11ShareHandleImage.cpp
gfx/layers/Layers.cpp
gfx/layers/PaintThread.cpp
gfx/layers/RotatedBuffer.cpp
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/SimpleVelocityTracker.cpp
gfx/layers/client/MultiTiledContentClient.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/client/TextureClientPool.cpp
gfx/layers/client/TiledContentClient.cpp
gfx/layers/composite/ContainerLayerComposite.cpp
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/MLGDeviceD3D11.cpp
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorManagerChild.cpp
gfx/layers/ipc/CompositorVsyncScheduler.cpp
gfx/layers/ipc/SharedSurfacesChild.cpp
gfx/layers/mlgpu/MLGDevice.cpp
gfx/layers/mlgpu/RenderViewMLGPU.cpp
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/src/DriverCrashGuard.cpp
gfx/thebes/D3D11Checks.cpp
gfx/thebes/DeviceManagerDx.cpp
gfx/thebes/gfxAndroidPlatform.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatformFontList.cpp
gfx/thebes/gfxPlatformGtk.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxWindowsPlatform.cpp
gfx/vr/VRManager.cpp
gfx/vr/ipc/VRProcessManager.cpp
gfx/vr/ipc/VRProcessParent.cpp
gfx/vr/service/OSVRSession.cpp
gfx/vr/service/OculusSession.cpp
gfx/vr/service/OpenVRSession.cpp
gfx/webrender_bindings/RenderCompositorOGL.cpp
image/AnimationSurfaceProvider.cpp
image/DecodePool.cpp
image/DecodedSurfaceProvider.cpp
image/FrameAnimator.cpp
image/FrameAnimator.h
image/RasterImage.cpp
image/SurfaceCache.cpp
image/imgLoader.cpp
image/test/gtest/TestSurfaceCache.cpp
layout/base/PresShell.cpp
layout/base/nsLayoutUtils.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/painting/FrameLayerBuilder.cpp
layout/painting/nsDisplayList.cpp
modules/libpref/Preferences.cpp
modules/libpref/init/StaticPrefList.yaml
modules/libpref/init/StaticPrefListBegin.h
modules/libpref/init/StaticPrefList_accessibility.h
modules/libpref/init/generate_static_pref_list.py
modules/libpref/test/test_generate_static_pref_list.py
widget/GfxInfoBase.cpp
widget/cocoa/nsCocoaWindow.mm
widget/nsBaseWidget.cpp
--- a/dom/media/platforms/wmf/DXVA2Manager.cpp
+++ b/dom/media/platforms/wmf/DXVA2Manager.cpp
@@ -675,32 +675,32 @@ D3D11DXVA2Manager::Init(layers::KnowsCom
   if (layers::ImageBridgeChild::GetSingleton() || !aKnowsCompositor) {
     // There's no proper KnowsCompositor for ImageBridge currently (and it
     // implements the interface), so just use that if it's available.
     mTextureClientAllocator = new D3D11RecycleAllocator(
         layers::ImageBridgeChild::GetSingleton().get(), mDevice,
         gfx::SurfaceFormat::NV12);
 
     if (ImageBridgeChild::GetSingleton() &&
-        StaticPrefs::media_wmf_use_sync_texture() &&
+        StaticPrefs::media_wmf_use_sync_texture_AtStartup() &&
         mDevice != DeviceManagerDx::Get()->GetCompositorDevice()) {
       // We use a syncobject to avoid the cost of the mutex lock when
       // compositing, and because it allows color conversion ocurring directly
       // from this texture DXVA does not seem to accept IDXGIKeyedMutex textures
       // as input.
       mSyncObject = layers::SyncObjectClient::CreateSyncObjectClient(
           layers::ImageBridgeChild::GetSingleton()
               ->GetTextureFactoryIdentifier()
               .mSyncHandle,
           mDevice);
     }
   } else {
     mTextureClientAllocator = new D3D11RecycleAllocator(
         aKnowsCompositor, mDevice, gfx::SurfaceFormat::NV12);
-    if (StaticPrefs::media_wmf_use_sync_texture()) {
+    if (StaticPrefs::media_wmf_use_sync_texture_AtStartup()) {
       // We use a syncobject to avoid the cost of the mutex lock when
       // compositing, and because it allows color conversion ocurring directly
       // from this texture DXVA does not seem to accept IDXGIKeyedMutex textures
       // as input.
       mSyncObject = layers::SyncObjectClient::CreateSyncObjectClient(
           aKnowsCompositor->GetTextureFactoryIdentifier().mSyncHandle, mDevice);
     }
   }
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -84,17 +84,17 @@ void WMFDecoderModule::Init() {
     testForVPx = sDXVAEnabled = true;
   } else {
     // Only allow DXVA in the UI process if we aren't in e10s Firefox
     testForVPx = sDXVAEnabled = !mozilla::BrowserTabsRemoteAutostart();
   }
 
   sDXVAEnabled = sDXVAEnabled && gfx::gfxVars::CanUseHardwareVideoDecoding();
   testForVPx = testForVPx && gfx::gfxVars::CanUseHardwareVideoDecoding();
-  if (testForVPx && StaticPrefs::media_wmf_vp9_enabled()) {
+  if (testForVPx && StaticPrefs::media_wmf_vp9_enabled_AtStartup()) {
     gfx::WMFVPXVideoCrashGuard guard;
     if (!guard.Crashed()) {
       sUsableVPXMFT = CanCreateMFTDecoder(CLSID_WebmMfVpxDec);
     }
   }
 }
 
 /* static */
--- a/gfx/2d/HelpersWinFonts.h
+++ b/gfx/2d/HelpersWinFonts.h
@@ -10,17 +10,17 @@ namespace mozilla {
 namespace gfx {
 
 extern BYTE sSystemTextQuality;
 
 static BYTE GetSystemTextQuality() { return sSystemTextQuality; }
 
 static AntialiasMode GetSystemDefaultAAMode() {
   AntialiasMode defaultMode = AntialiasMode::SUBPIXEL;
-  if (StaticPrefs::gfx_text_disable_aa()) {
+  if (StaticPrefs::gfx_text_disable_aa_AtStartup()) {
     return AntialiasMode::NONE;
   }
 
   switch (GetSystemTextQuality()) {
     case CLEARTYPE_QUALITY:
       defaultMode = AntialiasMode::SUBPIXEL;
       break;
     case ANTIALIASED_QUALITY:
--- a/gfx/2d/ScaledFontBase.cpp
+++ b/gfx/2d/ScaledFontBase.cpp
@@ -31,17 +31,17 @@ Atomic<uint32_t> UnscaledFont::sDeletion
 
 UnscaledFont::~UnscaledFont() { sDeletionCounter++; }
 
 Atomic<uint32_t> ScaledFont::sDeletionCounter(0);
 
 ScaledFont::~ScaledFont() { sDeletionCounter++; }
 
 AntialiasMode ScaledFont::GetDefaultAAMode() {
-  if (StaticPrefs::gfx_text_disable_aa()) {
+  if (StaticPrefs::gfx_text_disable_aa_AtStartup()) {
     return AntialiasMode::NONE;
   }
 
   return AntialiasMode::DEFAULT;
 }
 
 ScaledFontBase::~ScaledFontBase() {
 #ifdef USE_SKIA
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -272,17 +272,18 @@ uint8_t GLContext::ChooseDebugFlags(cons
 GLContext::GLContext(CreateContextFlags flags, const SurfaceCaps& caps,
                      GLContext* sharedContext, bool isOffscreen,
                      bool useTLSIsCurrent)
     : mUseTLSIsCurrent(ShouldUseTLSIsCurrent(useTLSIsCurrent)),
       mIsOffscreen(isOffscreen),
       mDebugFlags(ChooseDebugFlags(flags)),
       mSharedContext(sharedContext),
       mCaps(caps),
-      mWorkAroundDriverBugs(StaticPrefs::gfx_work_around_driver_bugs()) {
+      mWorkAroundDriverBugs(
+          StaticPrefs::gfx_work_around_driver_bugs_AtStartup()) {
   mOwningThreadId = PlatformThread::CurrentId();
   MOZ_ALWAYS_TRUE(sCurrentContext.init());
   sCurrentContext.set(0);
 }
 
 GLContext::~GLContext() {
   NS_ASSERTION(
       IsDestroyed(),
--- a/gfx/gl/GLLibraryEGL.cpp
+++ b/gfx/gl/GLLibraryEGL.cpp
@@ -81,17 +81,17 @@ PRLibrary* LoadApitraceLibrary() {
   // on android as we can use LD_PRELOAD or other tricks
   // on other platforms. We look for it in /data/local
   // as that's writeable by all users.
   path = "/data/local/tmp/egltrace.so";
 #endif
   if (!path) return nullptr;
 
   // Initialization of gfx prefs here is only needed during the unit tests...
-  if (!StaticPrefs::gfx_apitrace_enabled()) {
+  if (!StaticPrefs::gfx_apitrace_enabled_AtStartup()) {
     return nullptr;
   }
 
   static PRLibrary* sApitraceLibrary = nullptr;
   if (sApitraceLibrary) return sApitraceLibrary;
 
   nsAutoCString logFile;
   Preferences::GetCString("gfx.apitrace.logfile", logFile);
--- a/gfx/gl/GfxTexturesReporter.cpp
+++ b/gfx/gl/GfxTexturesReporter.cpp
@@ -54,25 +54,25 @@ static std::string FormatBytes(size_t am
 /* static */
 void GfxTexturesReporter::UpdateAmount(MemoryUse action, size_t amount) {
   if (action == MemoryFreed) {
     MOZ_RELEASE_ASSERT(
         amount <= sAmount,
         "GFX: Current texture usage greater than update amount.");
     sAmount -= amount;
 
-    if (StaticPrefs::gfx_logging_texture_usage_enabled()) {
+    if (StaticPrefs::gfx_logging_texture_usage_enabled_AtStartup()) {
       printf_stderr("Current texture usage: %s\n",
                     FormatBytes(sAmount).c_str());
     }
   } else {
     sAmount += amount;
     if (sAmount > sPeakAmount) {
       sPeakAmount.exchange(sAmount);
-      if (StaticPrefs::gfx_logging_peak_texture_usage_enabled()) {
+      if (StaticPrefs::gfx_logging_peak_texture_usage_enabled_AtStartup()) {
         printf_stderr("Peak texture usage: %s\n",
                       FormatBytes(sPeakAmount).c_str());
       }
     }
   }
 
   CrashReporter::AnnotateTexturesSize(sAmount);
 }
--- a/gfx/ipc/GPUChild.cpp
+++ b/gfx/ipc/GPUChild.cpp
@@ -137,33 +137,33 @@ mozilla::ipc::IPCResult GPUChild::RecvIn
                                                       aShmem, aThreadId);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GPUChild::RecvCreateVRProcess() {
   // Make sure create VR process at the main process
   MOZ_ASSERT(XRE_IsParentProcess());
-  if (StaticPrefs::dom_vr_process_enabled()) {
+  if (StaticPrefs::dom_vr_process_enabled_AtStartup()) {
     VRProcessManager::Initialize();
     VRProcessManager* vr = VRProcessManager::Get();
     MOZ_ASSERT(vr, "VRProcessManager must be initialized first.");
 
     if (vr) {
       vr->LaunchVRProcess();
     }
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GPUChild::RecvShutdownVRProcess() {
   // Make sure stopping VR process at the main process
   MOZ_ASSERT(XRE_IsParentProcess());
-  if (StaticPrefs::dom_vr_process_enabled()) {
+  if (StaticPrefs::dom_vr_process_enabled_AtStartup()) {
     VRProcessManager::Shutdown();
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GPUChild::RecvNotifyUiObservers(
     const nsCString& aTopic) {
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -473,17 +473,17 @@ mozilla::ipc::IPCResult GPUParent::RecvR
       },
       [&](const uint32_t& aGeneration) {
         return GetSingleton()->SendFinishMemoryReport(aGeneration);
       });
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GPUParent::RecvShutdownVR() {
-  if (StaticPrefs::dom_vr_process_enabled()) {
+  if (StaticPrefs::dom_vr_process_enabled_AtStartup()) {
     VRGPUChild::Shutdown();
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult GPUParent::RecvUpdatePerfStatsCollectionMask(
     const uint64_t& aMask) {
   PerfStats::SetCollectionMask(static_cast<PerfStats::MetricMask>(aMask));
--- a/gfx/ipc/GPUProcessHost.cpp
+++ b/gfx/ipc/GPUProcessHost.cpp
@@ -57,17 +57,18 @@ bool GPUProcessHost::Launch(StringVector
   return true;
 }
 
 bool GPUProcessHost::WaitForLaunch() {
   if (mLaunchPhase == LaunchPhase::Complete) {
     return !!mGPUChild;
   }
 
-  int32_t timeoutMs = StaticPrefs::layers_gpu_process_startup_timeout_ms();
+  int32_t timeoutMs =
+      StaticPrefs::layers_gpu_process_startup_timeout_ms_AtStartup();
 
   // If one of the following environment variables are set we can effectively
   // ignore the timeout - as we can guarantee the compositor process will be
   // terminated
   if (PR_GetEnv("MOZ_DEBUG_CHILD_PROCESS") ||
       PR_GetEnv("MOZ_DEBUG_CHILD_PAUSE")) {
     timeoutMs = 0;
   }
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -379,18 +379,18 @@ void GPUProcessManager::OnProcessLaunchC
   CrashReporter::AnnotateCrashReport(
       CrashReporter::Annotation::GPUProcessLaunchCount,
       static_cast<int>(mNumProcessAttempts));
 }
 
 static bool ShouldLimitDeviceResets(uint32_t count, int32_t deltaMilliseconds) {
   // We decide to limit by comparing the amount of resets that have happened
   // and time since the last reset to two prefs.
-  int32_t timeLimit = StaticPrefs::gfx_device_reset_threshold_ms();
-  int32_t countLimit = StaticPrefs::gfx_device_reset_limit();
+  int32_t timeLimit = StaticPrefs::gfx_device_reset_threshold_ms_AtStartup();
+  int32_t countLimit = StaticPrefs::gfx_device_reset_limit_AtStartup();
 
   bool hasTimeLimit = timeLimit >= 0;
   bool hasCountLimit = countLimit >= 0;
 
   bool triggeredTime = deltaMilliseconds < timeLimit;
   bool triggeredCount = count > (uint32_t)countLimit;
 
   // If we have both prefs set then it needs to trigger both limits,
--- a/gfx/layers/D3D11ShareHandleImage.cpp
+++ b/gfx/layers/D3D11ShareHandleImage.cpp
@@ -251,17 +251,17 @@ already_AddRefed<TextureClient> D3D11Rec
   // we could not reuse old D3D11Textures. It could cause video flickering.
   RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetImageDevice();
   if (!!mImageDevice && mImageDevice != device) {
     ShrinkToMinimumSize();
   }
   mImageDevice = device;
 
   TextureAllocationFlags allocFlags = TextureAllocationFlags::ALLOC_DEFAULT;
-  if (StaticPrefs::media_wmf_use_sync_texture() ||
+  if (StaticPrefs::media_wmf_use_sync_texture_AtStartup() ||
       mDevice == DeviceManagerDx::Get()->GetCompositorDevice()) {
     // If our device is the compositor device, we don't need any synchronization
     // in practice.
     allocFlags = TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION;
   }
 
   D3D11TextureClientAllocationHelper helper(mUsableSurfaceFormat, aColorSpace,
                                             aSize, allocFlags, mDevice,
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -139,17 +139,18 @@ already_AddRefed<ImageContainer> LayerMa
 }
 
 bool LayerManager::LayersComponentAlphaEnabled() {
   // If MOZ_GFX_OPTIMIZE_MOBILE is defined, we force component alpha off
   // and ignore the preference.
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
   return false;
 #else
-  return StaticPrefs::layers_componentalpha_enabled_DoNotUseDirectly();
+  return StaticPrefs::
+      layers_componentalpha_enabled_AtStartup_DoNotUseDirectly();
 #endif
 }
 
 bool LayerManager::AreComponentAlphaLayersEnabled() {
   return LayerManager::LayersComponentAlphaEnabled();
 }
 
 /*static*/
--- a/gfx/layers/PaintThread.cpp
+++ b/gfx/layers/PaintThread.cpp
@@ -43,17 +43,17 @@ PaintThread::PaintThread() {}
 
 void PaintThread::Release() {}
 
 void PaintThread::AddRef() {}
 
 /* static */
 int32_t PaintThread::CalculatePaintWorkerCount() {
   int32_t cpuCores = PR_GetNumberOfProcessors();
-  int32_t workerCount = StaticPrefs::layers_omtp_paint_workers();
+  int32_t workerCount = StaticPrefs::layers_omtp_paint_workers_AtStartup();
 
   // If not manually specified, default to (cpuCores * 3) / 4, and clamp
   // between 1 and 4. If a user wants more, they can manually specify it
   if (workerCount < 1) {
     workerCount = std::min(std::max((cpuCores * 3) / 4, 1), 4);
   }
 
   return workerCount;
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -71,17 +71,17 @@ Rect RotatedBuffer::GetSourceRectangle(X
 }
 
 void RotatedBuffer::BeginCapture() {
   RefPtr<gfx::DrawTarget> target = GetBufferTarget();
 
   MOZ_ASSERT(!mCapture);
   MOZ_ASSERT(target);
   mCapture = Factory::CreateCaptureDrawTargetForTarget(
-      target, StaticPrefs::layers_omtp_capture_limit());
+      target, StaticPrefs::layers_omtp_capture_limit_AtStartup());
 }
 
 RefPtr<gfx::DrawTargetCapture> RotatedBuffer::EndCapture() {
   MOZ_ASSERT(mCapture);
   return std::move(mCapture);
 }
 
 /**
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -606,17 +606,17 @@ APZCTreeManager::UpdateHitTestingTreeImp
   SendSubtreeTransformsToChromeMainThread(nullptr);
 }
 
 void APZCTreeManager::UpdateFocusState(LayersId aRootLayerTreeId,
                                        LayersId aOriginatingLayersId,
                                        const FocusTarget& aFocusTarget) {
   AssertOnUpdaterThread();
 
-  if (!StaticPrefs::apz_keyboard_enabled()) {
+  if (!StaticPrefs::apz_keyboard_enabled_AtStartup()) {
     return;
   }
 
   mFocusState.Update(aRootLayerTreeId, aOriginatingLayersId, aFocusTarget);
 }
 
 void APZCTreeManager::UpdateHitTestingTree(Layer* aRoot, bool aIsFirstPaint,
                                            LayersId aOriginatingLayersId,
@@ -1543,17 +1543,17 @@ nsEventStatus APZCTreeManager::ReceiveIn
         apzc->GetGuid(aOutTargetGuid);
         tapInput.mPoint = *untransformedPoint;
       }
       break;
     }
     case KEYBOARD_INPUT: {
       // Disable async keyboard scrolling when accessibility.browsewithcaret is
       // enabled
-      if (!StaticPrefs::apz_keyboard_enabled() ||
+      if (!StaticPrefs::apz_keyboard_enabled_AtStartup() ||
           StaticPrefs::accessibility_browsewithcaret()) {
         APZ_KEY_LOG("Skipping key input from invalid prefs\n");
         return result;
       }
 
       KeyboardInput& keyInput = aEvent.AsKeyboardInput();
 
       // Try and find a matching shortcut for this keyboard input
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -811,20 +811,20 @@ void AsyncPanZoomController::InitializeG
   sInitialized = true;
 
   MOZ_ASSERT(NS_IsMainThread());
 
   gZoomAnimationFunction =
       new ComputedTimingFunction(nsTimingFunction(StyleTimingKeyword::Ease));
   ClearOnShutdown(&gZoomAnimationFunction);
   gVelocityCurveFunction = new ComputedTimingFunction(
-      nsTimingFunction(StaticPrefs::apz_fling_curve_function_x1(),
-                       StaticPrefs::apz_fling_curve_function_y1(),
-                       StaticPrefs::apz_fling_curve_function_x2(),
-                       StaticPrefs::apz_fling_curve_function_y2()));
+      nsTimingFunction(StaticPrefs::apz_fling_curve_function_x1_AtStartup(),
+                       StaticPrefs::apz_fling_curve_function_y1_AtStartup(),
+                       StaticPrefs::apz_fling_curve_function_x2_AtStartup(),
+                       StaticPrefs::apz_fling_curve_function_y2_AtStartup()));
   ClearOnShutdown(&gVelocityCurveFunction);
 
   uint64_t sysmem = PR_GetPhysicalMemorySize();
   uint64_t threshold = 1LL << 32;  // 4 GB in bytes
   gIsHighMemSystem = sysmem >= threshold;
 
   PlatformSpecificState::InitializeGlobalState();
 }
@@ -842,17 +842,17 @@ AsyncPanZoomController::AsyncPanZoomCont
       mTreeManager(aTreeManager),
       mRecursiveMutex("AsyncPanZoomController"),
       mLastContentPaintMetrics(mLastContentPaintMetadata.GetMetrics()),
       mX(this),
       mY(this),
       mPanDirRestricted(false),
       mPinchLocked(false),
       mPinchEventBuffer(TimeDuration::FromMilliseconds(
-          StaticPrefs::apz_pinch_lock_buffer_max_age())),
+          StaticPrefs::apz_pinch_lock_buffer_max_age_AtStartup())),
       mZoomConstraints(false, false,
                        mScrollMetadata.GetMetrics().GetDevPixelsPerCSSPixel() *
                            kViewportMinScale / ParentLayerToScreenScale(1),
                        mScrollMetadata.GetMetrics().GetDevPixelsPerCSSPixel() *
                            kViewportMaxScale / ParentLayerToScreenScale(1)),
       mLastSampleTime(GetFrameTime()),
       mLastCheckerboardReport(GetFrameTime()),
       mOverscrollEffect(MakeUnique<OverscrollEffect>(*this)),
@@ -1049,17 +1049,17 @@ nsEventStatus AsyncPanZoomController::Ha
 
   const ScrollbarData& scrollbarData = node->GetScrollbarData();
   MOZ_ASSERT(scrollbarData.mScrollbarLayerType ==
              layers::ScrollbarLayerType::Thumb);
   MOZ_ASSERT(scrollbarData.mDirection.isSome());
   ScrollDirection direction = *scrollbarData.mDirection;
 
   bool isMouseAwayFromThumb = false;
-  if (int snapMultiplier = StaticPrefs::slider_snapMultiplier()) {
+  if (int snapMultiplier = StaticPrefs::slider_snapMultiplier_AtStartup()) {
     // It's fine to ignore the async component of the thumb's transform,
     // because any async transform of the thumb will be in the direction of
     // scrolling, but here we're interested in the other direction.
     ParentLayerRect thumbRect =
         (node->GetTransform() * AsyncTransformMatrix())
             .TransformBounds(LayerRect(node->GetVisibleRegion().GetBounds()));
     ScrollDirection otherDirection = GetPerpendicularDirection(direction);
     ParentLayerCoord distance =
@@ -5086,17 +5086,17 @@ void AsyncPanZoomController::DispatchSta
 
   if (RefPtr<GeckoContentController> controller = GetGeckoContentController()) {
     if (!IsTransformingState(aOldState) && IsTransformingState(aNewState)) {
       controller->NotifyAPZStateChange(GetGuid(),
                                        APZStateChange::eTransformBegin);
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
       // Let the compositor know about scroll state changes so it can manage
       // windowed plugins.
-      if (StaticPrefs::gfx_e10s_hide_plugins_for_scroll() &&
+      if (StaticPrefs::gfx_e10s_hide_plugins_for_scroll_AtStartup() &&
           mCompositorController) {
         mCompositorController->ScheduleHideAllPluginWindows();
       }
 #endif
     } else if (IsTransformingState(aOldState) &&
                !IsTransformingState(aNewState)) {
 #if defined(MOZ_WIDGET_ANDROID)
       // The Android UI thread only shows overlay UI elements when the content
@@ -5109,17 +5109,17 @@ void AsyncPanZoomController::DispatchSta
           animator->UpdateRootFrameMetrics(Metrics());
         }
       }
 #endif
 
       controller->NotifyAPZStateChange(GetGuid(),
                                        APZStateChange::eTransformEnd);
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
-      if (StaticPrefs::gfx_e10s_hide_plugins_for_scroll() &&
+      if (StaticPrefs::gfx_e10s_hide_plugins_for_scroll_AtStartup() &&
           mCompositorController) {
         mCompositorController->ScheduleShowAllPluginWindows();
       }
 #endif
     }
   }
 }
 
--- a/gfx/layers/apz/src/SimpleVelocityTracker.cpp
+++ b/gfx/layers/apz/src/SimpleVelocityTracker.cpp
@@ -98,17 +98,18 @@ Maybe<float> SimpleVelocityTracker::Comp
   return Some(velocity);
 }
 
 void SimpleVelocityTracker::Clear() { mVelocityQueue.Clear(); }
 
 void SimpleVelocityTracker::AddVelocityToQueue(uint32_t aTimestampMs,
                                                float aVelocity) {
   mVelocityQueue.AppendElement(std::make_pair(aTimestampMs, aVelocity));
-  if (mVelocityQueue.Length() > StaticPrefs::apz_max_velocity_queue_size()) {
+  if (mVelocityQueue.Length() >
+      StaticPrefs::apz_max_velocity_queue_size_AtStartup()) {
     mVelocityQueue.RemoveElementAt(0);
   }
 }
 
 float SimpleVelocityTracker::ApplyFlingCurveToVelocity(float aVelocity) const {
   float newVelocity = aVelocity;
   if (StaticPrefs::apz_max_velocity_inches_per_ms() > 0.0f) {
     bool velocityIsNegative = (newVelocity < 0);
--- a/gfx/layers/client/MultiTiledContentClient.cpp
+++ b/gfx/layers/client/MultiTiledContentClient.cpp
@@ -261,17 +261,18 @@ void ClientMultiTiledLayerBuffer::Update
                          .PreScale(mResolution, mResolution)
                          .PreTranslate(-mTilingOrigin));
 
       mCallback(&mPaintedLayer, ctx, paintRegion, dirtyRegion,
                 DrawRegionClip::DRAW, nsIntRegion(), mCallbackData);
       ctx = nullptr;
 
       // Edge padding allows us to avoid resampling artifacts
-      if (StaticPrefs::layers_tiles_edge_padding() && mResolution == 1) {
+      if (StaticPrefs::layers_tiles_edge_padding_AtStartup() &&
+          mResolution == 1) {
         drawTarget->PadEdges(newValidRegion.MovedBy(-mTilingOrigin));
       }
 
       // Reset
       mPaintTiles.Clear();
       mTilingOrigin = IntPoint(std::numeric_limits<int32_t>::max(),
                                std::numeric_limits<int32_t>::max());
     }
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -286,23 +286,23 @@ static TextureType GetTextureType(gfx::S
   if (aLayersBackend == LayersBackend::LAYERS_OPENGL &&
       type == gfxSurfaceType::Xlib && aFormat != SurfaceFormat::A8 &&
       gl::sGLXLibrary.UseTextureFromPixmap()) {
     return TextureType::X11;
   }
 #endif
 
 #ifdef XP_MACOSX
-  if (StaticPrefs::gfx_use_iosurface_textures()) {
+  if (StaticPrefs::gfx_use_iosurface_textures_AtStartup()) {
     return TextureType::MacIOSurface;
   }
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
-  if (StaticPrefs::gfx_use_surfacetexture_textures()) {
+  if (StaticPrefs::gfx_use_surfacetexture_textures_AtStartup()) {
     return TextureType::AndroidNativeWindow;
   }
 #endif
 
   return TextureType::Unknown;
 }
 
 static bool ShouldRemoteTextureType(TextureType aTextureType,
--- a/gfx/layers/client/TextureClientPool.cpp
+++ b/gfx/layers/client/TextureClientPool.cpp
@@ -136,17 +136,17 @@ void TextureClientPool::AllocateTextureC
 
   if (mSupportsTextureDirectMapping &&
       std::max(mSize.width, mSize.height) <= mMaxTextureSize) {
     allocFlags =
         TextureAllocationFlags(allocFlags | ALLOC_ALLOW_DIRECT_MAPPING);
   }
 
   RefPtr<TextureClient> newClient;
-  if (StaticPrefs::layers_force_shmem_tiles()) {
+  if (StaticPrefs::layers_force_shmem_tiles_AtStartup()) {
     // gfx::BackendType::NONE means use the content backend
     newClient = TextureClient::CreateForRawBufferAccess(
         mSurfaceAllocator, mFormat, mSize, gfx::BackendType::NONE, mBackend,
         mFlags, allocFlags);
   } else {
     newClient = TextureClient::CreateForDrawing(
         mSurfaceAllocator, mFormat, mSize, mBackend, mMaxTextureSize,
         BackendSelector::Content, mFlags, allocFlags);
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -673,17 +673,17 @@ Maybe<AcquiredBackBuffer> TileClient::Ac
   } else {
     target = backBuffer;
   }
 
   // Construct a capture draw target if necessary
   RefPtr<DrawTargetCapture> capture;
   if (aFlags & TilePaintFlags::Async) {
     capture = Factory::CreateCaptureDrawTargetForTarget(
-        target, StaticPrefs::layers_omtp_capture_limit());
+        target, StaticPrefs::layers_omtp_capture_limit_AtStartup());
     target = capture;
   }
 
   // Gather texture clients
   AutoTArray<RefPtr<TextureClient>, 4> clients;
   clients.AppendElement(RefPtr<TextureClient>(mBackBuffer));
   if (mBackBufferOnWhite) {
     clients.AppendElement(mBackBufferOnWhite);
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -468,17 +468,17 @@ void RenderLayers(ContainerT* aContainer
 
       if (geometry && isLeafLayer) {
         TransformLayerGeometry(layer, geometry);
       }
 
       layerToRender->RenderLayer(clipRect, geometry);
     }
 
-    if (StaticPrefs::layers_uniformity_info()) {
+    if (StaticPrefs::layers_uniformity_info_AtStartup()) {
       PrintUniformityInfo(layer);
     }
 
     if (StaticPrefs::layers_draw_layer_info()) {
       DrawLayerInfo(preparedData.mClipRect, aManager, layer);
     }
 
     // Draw a border around scrollable layers.
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -105,17 +105,17 @@ CompositorD3D11::CompositorD3D11(Composi
       mWindowRTCopy(nullptr),
       mAttachments(nullptr),
       mHwnd(nullptr),
       mDisableSequenceForNextFrame(false),
       mAllowPartialPresents(false),
       mIsDoubleBuffered(false),
       mVerifyBuffersFailed(false),
       mUseMutexOnPresent(false) {
-  mUseMutexOnPresent = StaticPrefs::gfx_use_mutex_on_present();
+  mUseMutexOnPresent = StaticPrefs::gfx_use_mutex_on_present_AtStartup();
 }
 
 CompositorD3D11::~CompositorD3D11() {}
 
 template <typename VertexType>
 void CompositorD3D11::SetVertexBuffer(ID3D11Buffer* aBuffer) {
   UINT size = sizeof(VertexType);
   UINT offset = 0;
--- a/gfx/layers/d3d11/MLGDeviceD3D11.cpp
+++ b/gfx/layers/d3d11/MLGDeviceD3D11.cpp
@@ -318,17 +318,17 @@ RefPtr<MLGRenderTarget> MLGSwapChainD3D1
   if (FAILED(hr)) {
     gfxCriticalNote << "Failed to acquire swap chain's backbuffer: "
                     << hexa(hr);
     return nullptr;
   }
 
   if (!mRT) {
     MLGRenderTargetFlags flags = MLGRenderTargetFlags::Default;
-    if (StaticPrefs::layers_mlgpu_enable_depth_buffer()) {
+    if (StaticPrefs::layers_mlgpu_enable_depth_buffer_AtStartup()) {
       flags |= MLGRenderTargetFlags::ZBuffer;
     }
 
     mRT = new MLGRenderTargetD3D11(mSize, flags);
     if (!mRT->Initialize(mDevice, nullptr)) {
       return nullptr;
     }
   }
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -887,20 +887,20 @@ TextureClientPool* CompositorBridgeChild
       return mTexturePools[i];
     }
   }
 
   mTexturePools.AppendElement(new TextureClientPool(
       aAllocator->GetCompositorBackendType(),
       aAllocator->SupportsTextureDirectMapping(),
       aAllocator->GetMaxTextureSize(), aFormat, gfx::gfxVars::TileSize(),
-      aFlags, StaticPrefs::layers_tile_pool_shrink_timeout(),
-      StaticPrefs::layers_tile_pool_clear_timeout(),
-      StaticPrefs::layers_tile_initial_pool_size(),
-      StaticPrefs::layers_tile_pool_unused_size(), this));
+      aFlags, StaticPrefs::layers_tile_pool_shrink_timeout_AtStartup(),
+      StaticPrefs::layers_tile_pool_clear_timeout_AtStartup(),
+      StaticPrefs::layers_tile_initial_pool_size_AtStartup(),
+      StaticPrefs::layers_tile_pool_unused_size_AtStartup(), this));
 
   return mTexturePools.LastElement();
 }
 
 void CompositorBridgeChild::HandleMemoryPressure() {
   for (size_t i = 0; i < mTexturePools.Length(); i++) {
     mTexturePools[i]->Clear();
   }
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1787,17 +1787,17 @@ PWebRenderBridgeParent* CompositorBridge
   apis.AppendElement(
       wr::WebRenderAPI::Create(this, std::move(widget), windowId, aSize));
   if (!apis[0]) {
     mWrBridge = WebRenderBridgeParent::CreateDestroyed(aPipelineId);
     mWrBridge.get()->AddRef();  // IPDL reference
     return mWrBridge;
   }
 
-  if (StaticPrefs::gfx_webrender_split_render_roots()) {
+  if (StaticPrefs::gfx_webrender_split_render_roots_AtStartup()) {
     apis.AppendElement(
         apis[0]->CreateDocument(aSize, 1, wr::RenderRoot::Content));
     apis.AppendElement(
         apis[0]->CreateDocument(aSize, 2, wr::RenderRoot::Popover));
   }
 
   nsTArray<RefPtr<wr::WebRenderAPI>> clonedApis;
   for (auto& api : apis) {
--- a/gfx/layers/ipc/CompositorManagerChild.cpp
+++ b/gfx/layers/ipc/CompositorManagerChild.cpp
@@ -264,17 +264,18 @@ CompositorManagerChild::GetSpecificMessa
 
   return nullptr;
 }
 
 void CompositorManagerChild::SetReplyTimeout() {
 #ifndef DEBUG
   // Add a timeout for release builds to kill GPU process when it hangs.
   if (XRE_IsParentProcess() && GPUProcessManager::Get()->GetGPUChild()) {
-    int32_t timeout = StaticPrefs::layers_gpu_process_ipc_reply_timeout_ms();
+    int32_t timeout =
+        StaticPrefs::layers_gpu_process_ipc_reply_timeout_ms_AtStartup();
     SetReplyTimeoutMs(timeout);
   }
 #endif
 }
 
 bool CompositorManagerChild::ShouldContinueFromReplyTimeout() {
   if (XRE_IsParentProcess()) {
     gfxCriticalNote << "Killing GPU process due to IPC reply timeout";
--- a/gfx/layers/ipc/CompositorVsyncScheduler.cpp
+++ b/gfx/layers/ipc/CompositorVsyncScheduler.cpp
@@ -251,17 +251,17 @@ void CompositorVsyncScheduler::Composite
 
     mVsyncNotificationsSkipped = 0;
 
     TimeDuration compositeFrameTotal = TimeStamp::Now() - aVsyncTimestamp;
     mozilla::Telemetry::Accumulate(
         mozilla::Telemetry::COMPOSITE_FRAME_ROUNDTRIP_TIME,
         compositeFrameTotal.ToMilliseconds());
   } else if (mVsyncNotificationsSkipped++ >
-             StaticPrefs::gfx_vsync_compositor_unobserve_count()) {
+             StaticPrefs::gfx_vsync_compositor_unobserve_count_AtStartup()) {
     UnobserveVsync();
   }
 }
 
 void CompositorVsyncScheduler::ForceComposeToTarget(gfx::DrawTarget* aTarget,
                                                     const IntRect* aRect) {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
 
--- a/gfx/layers/ipc/SharedSurfacesChild.cpp
+++ b/gfx/layers/ipc/SharedSurfacesChild.cpp
@@ -507,33 +507,33 @@ void SharedSurfacesAnimation::Destroy() 
   }
 
   if (mKeys.IsEmpty()) {
     return;
   }
 
   for (const auto& entry : mKeys) {
     MOZ_ASSERT(!entry.mManager->IsDestroyed());
-    if (StaticPrefs::image_animated_decode_on_demand_recycle()) {
+    if (StaticPrefs::image_animated_decode_on_demand_recycle_AtStartup()) {
       entry.mManager->DeregisterAsyncAnimation(entry.mImageKey);
     }
     entry.mManager->AddImageKeyForDiscard(entry.mImageKey);
   }
 
   mKeys.Clear();
 }
 
 void SharedSurfacesAnimation::HoldSurfaceForRecycling(
     AnimationImageKeyData& aEntry, SourceSurface* aParentSurface,
     SourceSurfaceSharedData* aSurface) {
   if (aParentSurface == static_cast<SourceSurface*>(aSurface)) {
     return;
   }
 
-  MOZ_ASSERT(StaticPrefs::image_animated_decode_on_demand_recycle());
+  MOZ_ASSERT(StaticPrefs::image_animated_decode_on_demand_recycle_AtStartup());
   aEntry.mPendingRelease.AppendElement(aParentSurface);
 }
 
 nsresult SharedSurfacesAnimation::SetCurrentFrame(
     SourceSurface* aParentSurface, SourceSurfaceSharedData* aSurface,
     const gfx::IntRect& aDirtyRect) {
   MOZ_ASSERT(aSurface);
 
@@ -612,17 +612,17 @@ nsresult SharedSurfacesAnimation::Update
       aKey = entry.mImageKey;
       found = true;
       break;
     }
   }
 
   if (!found) {
     aKey = aManager->WrBridge()->GetNextImageKey();
-    if (StaticPrefs::image_animated_decode_on_demand_recycle()) {
+    if (StaticPrefs::image_animated_decode_on_demand_recycle_AtStartup()) {
       aManager->RegisterAsyncAnimation(aKey, this);
     }
 
     AnimationImageKeyData data(aManager, aKey);
     HoldSurfaceForRecycling(data, aParentSurface, aSurface);
     mKeys.AppendElement(std::move(data));
     aResources.AddExternalImage(mId, aKey);
   }
--- a/gfx/layers/mlgpu/MLGDevice.cpp
+++ b/gfx/layers/mlgpu/MLGDevice.cpp
@@ -80,31 +80,31 @@ bool MLGDevice::Initialize() {
     // StagingBuffer depends on this value being accurate, so for now we just
     // double-check it here.
     return Fail("FEATURE_FAILURE_MIN_MAX_CB_BIND_SIZE",
                 "Minimum constant buffer bind size not met");
   }
 
   // We allow this to be pref'd off for testing. Switching it off enables
   // Direct3D 11.0/Windows 7/OpenGL-style buffer code paths.
-  if (!StaticPrefs::layers_mlgpu_enable_buffer_sharing()) {
+  if (!StaticPrefs::layers_mlgpu_enable_buffer_sharing_AtStartup()) {
     gfxConfig::EnableFallback(Fallback::NO_CONSTANT_BUFFER_OFFSETTING,
                               "Disabled by pref");
     mCanUseConstantBufferOffsetBinding = false;
   }
   if (mCanUseConstantBufferOffsetBinding && !VerifyConstantBufferOffsetting()) {
     gfxConfig::EnableFallback(Fallback::NO_CONSTANT_BUFFER_OFFSETTING,
                               "Constant buffer offset binding does not work");
     mCanUseConstantBufferOffsetBinding = false;
   }
 
   // We allow this to be pref'd off for testing. Disabling it turns on
   // ID3D11DeviceContext1::ClearView support, which is present on
   // newer Windows 8+ drivers.
-  if (!StaticPrefs::layers_mlgpu_enable_clear_view()) {
+  if (!StaticPrefs::layers_mlgpu_enable_clear_view_AtStartup()) {
     mCanUseClearView = false;
   }
 
   // When compositing normal sized layer trees, we typically have small vertex
   // buffers. Empirically the vertex and pixel constant buffer sizes are
   // generally under 1KB and the vertex constant buffer size is under 8KB.
   static const size_t kDefaultVertexBufferSize = 4096;
   static const size_t kDefaultVSConstantBufferSize =
@@ -122,17 +122,17 @@ bool MLGDevice::Initialize() {
       MakeUnique<SharedConstantBuffer>(this, kDefaultPSConstantBufferSize);
 
   if (!mSharedVertexBuffer->Init() || !mSharedVSBuffer->Init() ||
       !mSharedPSBuffer->Init()) {
     return Fail("FEATURE_FAILURE_ALLOC_SHARED_BUFFER",
                 "Failed to allocate a shared shader buffer");
   }
 
-  if (StaticPrefs::layers_mlgpu_enable_buffer_cache()) {
+  if (StaticPrefs::layers_mlgpu_enable_buffer_cache_AtStartup()) {
     mConstantBufferCache = MakeUnique<BufferCache>(this);
   }
 
   mInitialized = true;
   mIsValid = true;
   return true;
 }
 
--- a/gfx/layers/mlgpu/RenderViewMLGPU.cpp
+++ b/gfx/layers/mlgpu/RenderViewMLGPU.cpp
@@ -69,17 +69,18 @@ RenderViewMLGPU::RenderViewMLGPU(FrameBu
       mDevice(aBuilder->GetDevice()),
       mParent(aParent),
       mContainer(nullptr),
       mFinishedBuilding(false),
       mCurrentLayerBufferIndex(kInvalidResourceIndex),
       mCurrentMaskRectBufferIndex(kInvalidResourceIndex),
       mCurrentDepthMode(MLGDepthTestMode::Disabled),
       mNextSortIndex(1),
-      mUseDepthBuffer(StaticPrefs::layers_mlgpu_enable_depth_buffer()),
+      mUseDepthBuffer(
+          StaticPrefs::layers_mlgpu_enable_depth_buffer_AtStartup()),
       mDepthBufferNeedsClear(false) {
   if (aParent) {
     aParent->AddChild(this);
   }
 }
 
 RenderViewMLGPU::~RenderViewMLGPU() {
   for (const auto& child : mChildren) {
@@ -183,17 +184,17 @@ void RenderViewMLGPU::AddItem(LayerMLGPU
 }
 
 bool RenderViewMLGPU::UpdateVisibleRegion(ItemInfo& aItem) {
   // If the item has some kind of complex transform, we perform a very
   // simple occlusion test and move on. We using a depth buffer we skip
   // CPU-based occlusion culling as well, since the GPU will do most of our
   // culling work for us.
   if (mUseDepthBuffer || !aItem.translation ||
-      !StaticPrefs::layers_mlgpu_enable_cpu_occlusion()) {
+      !StaticPrefs::layers_mlgpu_enable_cpu_occlusion_AtStartup()) {
     // Update the render region even if we won't compute visibility, since some
     // layer types (like Canvas and Image) need to have the visible region
     // clamped.
     LayerIntRegion region = aItem.layer->GetShadowVisibleRegion();
     aItem.layer->SetRenderRegion(std::move(region));
 
     AL_LOG("RenderView %p simple occlusion test, bounds=%s, translation?=%d\n",
            this, Stringify(aItem.bounds).c_str(), aItem.translation ? 1 : 0);
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -1776,17 +1776,17 @@ void CompositorOGL::EndFrame() {
 
   Compositor::EndFrame();
 }
 
 void CompositorOGL::InsertFrameDoneSync() {
 #ifdef XP_MACOSX
   // Only do this on macOS.
   // On other platforms, SwapBuffers automatically applies back-pressure.
-  if (StaticPrefs::gfx_core_animation_enabled()) {
+  if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
     if (mThisFrameDoneSync) {
       mGLContext->fDeleteSync(mThisFrameDoneSync);
     }
     mThisFrameDoneSync =
         mGLContext->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
   }
 #endif
 }
@@ -2011,17 +2011,17 @@ GLBlitTextureImageHelper* CompositorOGL:
 GLuint CompositorOGL::GetTemporaryTexture(GLenum aTarget, GLenum aUnit) {
   if (!mTexturePool) {
     mTexturePool = new PerUnitTexturePoolOGL(gl());
   }
   return mTexturePool->GetTexture(aTarget, aUnit);
 }
 
 bool CompositorOGL::SupportsTextureDirectMapping() {
-  if (!StaticPrefs::gfx_allow_texture_direct_mapping()) {
+  if (!StaticPrefs::gfx_allow_texture_direct_mapping_AtStartup()) {
     return false;
   }
 
   if (mGLContext) {
     mGLContext->MakeCurrent();
     return mGLContext->IsExtensionSupported(
                gl::GLContext::APPLE_client_storage) &&
            mGLContext->IsExtensionSupported(gl::GLContext::APPLE_texture_range);
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -70,17 +70,17 @@ void WebRenderBridgeChild::DoDestroy() {
   mDestroyed = true;
   mManager = nullptr;
 }
 
 void WebRenderBridgeChild::AddWebRenderParentCommand(
     const WebRenderParentCommand& aCmd, wr::RenderRoot aRenderRoot) {
   MOZ_ASSERT(aRenderRoot == wr::RenderRoot::Default ||
              (XRE_IsParentProcess() &&
-              StaticPrefs::gfx_webrender_split_render_roots()));
+              StaticPrefs::gfx_webrender_split_render_roots_AtStartup()));
   mParentCommands[aRenderRoot].AppendElement(aCmd);
 }
 
 void WebRenderBridgeChild::BeginTransaction() {
   MOZ_ASSERT(!mDestroyed);
 
   UpdateFwdTransactionId();
   mIsInTransaction = true;
@@ -115,17 +115,17 @@ void WebRenderBridgeChild::EndTransactio
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(mIsInTransaction);
 
   TimeStamp fwdTime = TimeStamp::Now();
 
   for (auto& renderRoot : aRenderRoots) {
     MOZ_ASSERT(renderRoot.mRenderRoot == wr::RenderRoot::Default ||
                (XRE_IsParentProcess() &&
-                StaticPrefs::gfx_webrender_split_render_roots()));
+                StaticPrefs::gfx_webrender_split_render_roots_AtStartup()));
     renderRoot.mCommands = std::move(mParentCommands[renderRoot.mRenderRoot]);
   }
 
   nsTArray<CompositionPayload> payloads;
   if (mManager) {
     mManager->TakeCompositionPayloads(payloads);
   }
 
@@ -153,17 +153,17 @@ void WebRenderBridgeChild::EndEmptyTrans
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(mIsInTransaction);
 
   TimeStamp fwdTime = TimeStamp::Now();
 
   for (auto& update : aRenderRootUpdates) {
     MOZ_ASSERT(update.mRenderRoot == wr::RenderRoot::Default ||
                (XRE_IsParentProcess() &&
-                StaticPrefs::gfx_webrender_split_render_roots()));
+                StaticPrefs::gfx_webrender_split_render_roots_AtStartup()));
     update.mCommands = std::move(mParentCommands[update.mRenderRoot]);
   }
 
   nsTArray<CompositionPayload> payloads;
   if (mManager) {
     mManager->TakeCompositionPayloads(payloads);
   }
 
@@ -182,17 +182,17 @@ void WebRenderBridgeChild::EndEmptyTrans
 }
 
 void WebRenderBridgeChild::ProcessWebRenderParentCommands() {
   MOZ_ASSERT(!mDestroyed);
 
   for (auto renderRoot : wr::kRenderRoots) {
     if (!mParentCommands[renderRoot].IsEmpty()) {
       MOZ_ASSERT(renderRoot == wr::RenderRoot::Default ||
-                 StaticPrefs::gfx_webrender_split_render_roots());
+                 StaticPrefs::gfx_webrender_split_render_roots_AtStartup());
       this->SendParentCommands(mParentCommands[renderRoot], renderRoot);
       mParentCommands[renderRoot].Clear();
     }
   }
 }
 
 void WebRenderBridgeChild::AddPipelineIdForAsyncCompositable(
     const wr::PipelineId& aPipelineId, const CompositableHandle& aHandle,
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -316,17 +316,17 @@ WebRenderBridgeParent::WebRenderBridgePa
   MOZ_ASSERT(mAnimStorage);
   mAsyncImageManager->AddPipeline(mPipelineId, this);
   if (IsRootWebRenderBridgeParent()) {
     MOZ_ASSERT(!mCompositorScheduler);
     mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
   }
 
   if (!IsRootWebRenderBridgeParent() &&
-      StaticPrefs::gfx_webrender_split_render_roots()) {
+      StaticPrefs::gfx_webrender_split_render_roots_AtStartup()) {
     mRenderRoot = wr::RenderRoot::Content;
   }
 
   for (auto& api : aApis) {
     MOZ_ASSERT(api);
     mApis[api->GetRenderRoot()] = api;
   }
 }
@@ -913,17 +913,17 @@ bool WebRenderBridgeParent::SetDisplayLi
     if (IsRootWebRenderBridgeParent()) {
       if (aRenderRoot != wr::RenderRoot::Default) {
         MutexAutoLock lock(mRenderRootRectMutex);
         mRenderRootRects[aRenderRoot] = ViewAs<ScreenPixel>(
             aRect, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
       }
       LayoutDeviceIntSize widgetSize = mWidget->GetClientSize();
       LayoutDeviceIntRect rect;
-      if (StaticPrefs::gfx_webrender_split_render_roots()) {
+      if (StaticPrefs::gfx_webrender_split_render_roots_AtStartup()) {
         rect = RoundedToInt(aRect);
         rect.SetWidth(
             std::max(0, std::min(widgetSize.width - rect.X(), rect.Width())));
         rect.SetHeight(
             std::max(0, std::min(widgetSize.height - rect.Y(), rect.Height())));
       } else {
         // XXX: If we can't have multiple documents, just use the
         // pre-document- splitting behavior of directly applying the client
@@ -1607,17 +1607,17 @@ mozilla::ipc::IPCResult WebRenderBridgeP
 mozilla::ipc::IPCResult WebRenderBridgeParent::RecvClearCachedResources() {
   if (mDestroyed) {
     return IPC_OK();
   }
 
   for (auto renderRoot : wr::kRenderRoots) {
     if (renderRoot == wr::RenderRoot::Default ||
         (IsRootWebRenderBridgeParent() &&
-         StaticPrefs::gfx_webrender_split_render_roots())) {
+         StaticPrefs::gfx_webrender_split_render_roots_AtStartup())) {
       // Clear resources
       wr::TransactionBuilder txn;
       txn.SetLowPriority(true);
       txn.ClearDisplayList(GetNextWrEpoch(), mPipelineId);
       txn.Notify(wr::Checkpoint::SceneBuilt,
                  MakeUnique<ScheduleObserveLayersUpdate>(
                      mCompositorBridge, GetLayersId(),
                      mChildLayersObserverEpoch, false));
@@ -1695,17 +1695,17 @@ mozilla::ipc::IPCResult WebRenderBridgeP
 void WebRenderBridgeParent::ScheduleForcedGenerateFrame() {
   if (mDestroyed) {
     return;
   }
 
   for (auto renderRoot : wr::kRenderRoots) {
     if (renderRoot == wr::RenderRoot::Default ||
         (IsRootWebRenderBridgeParent() &&
-         StaticPrefs::gfx_webrender_split_render_roots())) {
+         StaticPrefs::gfx_webrender_split_render_roots_AtStartup())) {
       wr::TransactionBuilder fastTxn(/* aUseSceneBuilderThread */ false);
       fastTxn.InvalidateRenderedFrame();
       Api(renderRoot)->SendTransaction(fastTxn);
     }
   }
 
   ScheduleGenerateFrameAllRenderRoots();
 }
@@ -1732,17 +1732,17 @@ mozilla::ipc::IPCResult WebRenderBridgeP
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetConfirmedTargetAPZC(
     const uint64_t& aBlockId, nsTArray<SLGuidAndRenderRoot>&& aTargets) {
   for (size_t i = 0; i < aTargets.Length(); i++) {
     // Guard against bad data from hijacked child processes
     if (aTargets[i].mRenderRoot > wr::kHighestRenderRoot ||
-        (!StaticPrefs::gfx_webrender_split_render_roots() &&
+        (!StaticPrefs::gfx_webrender_split_render_roots_AtStartup() &&
          aTargets[i].mRenderRoot != wr::RenderRoot::Default)) {
       NS_ERROR(
           "Unexpected render root in RecvSetConfirmedTargetAPZC; dropping "
           "message...");
       return IPC_FAIL(this, "Bad render root");
     }
     if (aTargets[i].mScrollableLayerGuid.mLayersId != GetLayersId()) {
       NS_ERROR(
--- a/gfx/src/DriverCrashGuard.cpp
+++ b/gfx/src/DriverCrashGuard.cpp
@@ -401,18 +401,18 @@ bool D3D11LayersCrashGuard::UpdateEnviro
     return false;
   }
 
   checked = true;
 
   bool changed = false;
   // Feature status.
 #if defined(XP_WIN)
-  bool d2dEnabled = StaticPrefs::gfx_direct2d_force_enabled() ||
-                    (!StaticPrefs::gfx_direct2d_disabled() &&
+  bool d2dEnabled = StaticPrefs::gfx_direct2d_force_enabled_AtStartup() ||
+                    (!StaticPrefs::gfx_direct2d_disabled_AtStartup() &&
                      FeatureEnabled(nsIGfxInfo::FEATURE_DIRECT2D));
   changed |= CheckAndUpdateBoolPref("feature-d2d", d2dEnabled);
 
   bool d3d11Enabled = gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING);
   changed |= CheckAndUpdateBoolPref("feature-d3d11", d3d11Enabled);
   if (changed) {
     RecordTelemetry(TelemetryState::EnvironmentChanged);
   }
--- a/gfx/thebes/D3D11Checks.cpp
+++ b/gfx/thebes/D3D11Checks.cpp
@@ -134,17 +134,17 @@ bool D3D11Checks::DoesRenderTargetViewNe
 /* static */
 bool D3D11Checks::DoesDeviceWork() {
   static bool checked = false;
   static bool result = false;
 
   if (checked) return result;
   checked = true;
 
-  if (StaticPrefs::gfx_direct2d_force_enabled() ||
+  if (StaticPrefs::gfx_direct2d_force_enabled_AtStartup() ||
       gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING)) {
     result = true;
     return true;
   }
 
   if (GetModuleHandleW(L"igd10umd32.dll")) {
     const wchar_t* checkModules[] = {L"dlumd32.dll", L"dlumd11.dll",
                                      L"dlumd10.dll"};
@@ -195,29 +195,29 @@ static bool TryCreateTexture2D(ID3D11Dev
 static bool DoesTextureSharingWorkInternal(ID3D11Device* device,
                                            DXGI_FORMAT format, UINT bindflags) {
   // CreateTexture2D is known to crash on lower feature levels, see bugs
   // 1170211 and 1089413.
   if (device->GetFeatureLevel() < D3D_FEATURE_LEVEL_10_0) {
     return false;
   }
 
-  if (StaticPrefs::gfx_direct2d_force_enabled() ||
+  if (StaticPrefs::gfx_direct2d_force_enabled_AtStartup() ||
       gfxConfig::IsForcedOnByUser(Feature::HW_COMPOSITING)) {
     return true;
   }
 
   if (GetModuleHandleW(L"atidxx32.dll")) {
     nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
     if (gfxInfo) {
       nsString vendorID, vendorID2;
       gfxInfo->GetAdapterVendorID(vendorID);
       gfxInfo->GetAdapterVendorID2(vendorID2);
       if (vendorID.EqualsLiteral("0x8086") && vendorID2.IsEmpty()) {
-        if (!StaticPrefs::layers_amd_switchable_gfx_enabled()) {
+        if (!StaticPrefs::layers_amd_switchable_gfx_enabled_AtStartup()) {
           return false;
         }
         gfxCriticalError(CriticalLog::DefaultOptions(false))
             << "PossiblyBrokenSurfaceSharing_UnexpectedAMDGPU";
       }
     }
   }
 
--- a/gfx/thebes/DeviceManagerDx.cpp
+++ b/gfx/thebes/DeviceManagerDx.cpp
@@ -178,17 +178,18 @@ static inline bool ProcessOwnsCompositor
 #endif
 
 bool DeviceManagerDx::CreateCompositorDevices() {
   MOZ_ASSERT(ProcessOwnsCompositor());
 
   FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
   MOZ_ASSERT(d3d11.IsEnabled());
 
-  if (int32_t sleepSec = StaticPrefs::gfx_direct3d11_sleep_on_create_device()) {
+  if (int32_t sleepSec =
+          StaticPrefs::gfx_direct3d11_sleep_on_create_device_AtStartup()) {
     printf_stderr("Attach to PID: %d\n", GetCurrentProcessId());
     Sleep(sleepSec * 1000);
   }
 
   if (!LoadD3D11()) {
     return false;
   }
 
@@ -496,17 +497,17 @@ bool DeviceManagerDx::CreateCompositorDe
 // whole graphics stack is blown away anyway. But just in case, we
 // make gpu process IDs negative and parent process IDs positive.
 static inline int32_t GetNextDeviceCounter() {
   static int32_t sDeviceCounter = 0;
   return XRE_IsGPUProcess() ? --sDeviceCounter : ++sDeviceCounter;
 }
 
 void DeviceManagerDx::CreateCompositorDevice(FeatureState& d3d11) {
-  if (StaticPrefs::layers_d3d11_force_warp()) {
+  if (StaticPrefs::layers_d3d11_force_warp_AtStartup()) {
     CreateWARPCompositorDevice();
     return;
   }
 
   RefPtr<IDXGIAdapter1> adapter = GetDXGIAdapter();
   if (!adapter) {
     d3d11.SetFailed(FeatureStatus::Unavailable,
                     "Failed to acquire a DXGI adapter",
@@ -566,30 +567,30 @@ void DeviceManagerDx::CreateCompositorDe
   }
   mCompositorDevice->SetExceptionMode(0);
 }
 
 bool DeviceManagerDx::CreateDevice(IDXGIAdapter* aAdapter,
                                    D3D_DRIVER_TYPE aDriverType, UINT aFlags,
                                    HRESULT& aResOut,
                                    RefPtr<ID3D11Device>& aOutDevice) {
-  if (StaticPrefs::gfx_direct3d11_enable_debug_layer() ||
-      StaticPrefs::gfx_direct3d11_break_on_error()) {
+  if (StaticPrefs::gfx_direct3d11_enable_debug_layer_AtStartup() ||
+      StaticPrefs::gfx_direct3d11_break_on_error_AtStartup()) {
     aFlags |= D3D11_CREATE_DEVICE_DEBUG;
   }
 
   MOZ_SEH_TRY {
     aResOut = sD3D11CreateDeviceFn(
         aAdapter, aDriverType, nullptr, aFlags, mFeatureLevels.Elements(),
         mFeatureLevels.Length(), D3D11_SDK_VERSION, getter_AddRefs(aOutDevice),
         nullptr, nullptr);
   }
   MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { return false; }
 
-  if (StaticPrefs::gfx_direct3d11_break_on_error()) {
+  if (StaticPrefs::gfx_direct3d11_break_on_error_AtStartup()) {
     do {
       if (!aOutDevice) break;
 
       RefPtr<ID3D11Debug> debug;
       if (!SUCCEEDED(aOutDevice->QueryInterface(__uuidof(ID3D11Debug),
                                                 getter_AddRefs(debug))))
         break;
 
@@ -614,18 +615,18 @@ bool DeviceManagerDx::CreateDevice(IDXGI
       infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
     } while (false);
   }
 
   return true;
 }
 
 void DeviceManagerDx::CreateWARPCompositorDevice() {
-  ScopedGfxFeatureReporter reporterWARP("D3D11-WARP",
-                                        StaticPrefs::layers_d3d11_force_warp());
+  ScopedGfxFeatureReporter reporterWARP(
+      "D3D11-WARP", StaticPrefs::layers_d3d11_force_warp_AtStartup());
   FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
 
   HRESULT hr;
   RefPtr<ID3D11Device> device;
 
   // Use D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
   // to prevent bug 1092260. IE 11 also uses this flag.
   UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -88,17 +88,17 @@ gfxAndroidPlatform::gfxAndroidPlatform()
 
   Factory::SetFTLibrary(gPlatformFTLibrary);
 
   RegisterStrongMemoryReporter(new FreetypeReporter());
 
   mOffscreenFormat = GetScreenDepth() == 16 ? SurfaceFormat::R5G6B5_UINT16
                                             : SurfaceFormat::X8R8G8B8_UINT32;
 
-  if (StaticPrefs::gfx_android_rgb16_force()) {
+  if (StaticPrefs::gfx_android_rgb16_force_AtStartup()) {
     mOffscreenFormat = SurfaceFormat::R5G6B5_UINT16;
   }
 }
 
 gfxAndroidPlatform::~gfxAndroidPlatform() {
   FT_Done_Library(gPlatformFTLibrary);
   gPlatformFTLibrary = nullptr;
 }
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -602,17 +602,17 @@ static uint32_t GetSkiaGlyphCacheSize() 
   // Only increase font cache size on non-android to save memory.
 #  if !defined(MOZ_WIDGET_ANDROID)
   // 10mb as the default pref cache size on desktop due to talos perf tweaking.
   // Chromium uses 20mb and skia default uses 2mb.
   // We don't need to change the font cache count since we usually
   // cache thrash due to asian character sets in talos.
   // Only increase memory on the content process
   uint32_t cacheSize =
-      StaticPrefs::gfx_content_skia_font_cache_size() * 1024 * 1024;
+      StaticPrefs::gfx_content_skia_font_cache_size_AtStartup() * 1024 * 1024;
   if (mozilla::BrowserTabsRemoteAutostart()) {
     return XRE_IsContentProcess() ? cacheSize : kDefaultGlyphCacheSize;
   }
 
   return cacheSize;
 #  else
   return kDefaultGlyphCacheSize;
 #  endif  // MOZ_WIDGET_ANDROID
@@ -908,37 +908,40 @@ void gfxPlatform::Init() {
 
   // Drop a note in the crash report if we end up forcing an option that could
   // destabilize things.  New items should be appended at the end (of an
   // existing or in a new section), so that we don't have to know the version to
   // interpret these cryptic strings.
   {
     nsAutoCString forcedPrefs;
     // D2D prefs
-    forcedPrefs.AppendPrintf("FP(D%d%d", StaticPrefs::gfx_direct2d_disabled(),
-                             StaticPrefs::gfx_direct2d_force_enabled());
+    forcedPrefs.AppendPrintf(
+        "FP(D%d%d", StaticPrefs::gfx_direct2d_disabled_AtStartup(),
+        StaticPrefs::gfx_direct2d_force_enabled_AtStartup());
     // Layers prefs
     forcedPrefs.AppendPrintf(
-        "-L%d%d%d%d", StaticPrefs::layers_amd_switchable_gfx_enabled(),
-        StaticPrefs::layers_acceleration_disabled_DoNotUseDirectly(),
-        StaticPrefs::layers_acceleration_force_enabled_DoNotUseDirectly(),
-        StaticPrefs::layers_d3d11_force_warp());
+        "-L%d%d%d%d",
+        StaticPrefs::layers_amd_switchable_gfx_enabled_AtStartup(),
+        StaticPrefs::layers_acceleration_disabled_AtStartup_DoNotUseDirectly(),
+        StaticPrefs::
+            layers_acceleration_force_enabled_AtStartup_DoNotUseDirectly(),
+        StaticPrefs::layers_d3d11_force_warp_AtStartup());
     // WebGL prefs
     forcedPrefs.AppendPrintf(
         "-W%d%d%d%d%d%d%d%d", StaticPrefs::webgl_angle_force_d3d11(),
         StaticPrefs::webgl_angle_force_warp(), StaticPrefs::webgl_disabled(),
         StaticPrefs::webgl_disable_angle(), StaticPrefs::webgl_dxgl_enabled(),
         StaticPrefs::webgl_force_enabled(),
         StaticPrefs::webgl_force_layers_readback(),
         StaticPrefs::webgl_msaa_force());
     // Prefs that don't fit into any of the other sections
     forcedPrefs.AppendPrintf("-T%d%d%d) ",
-                             StaticPrefs::gfx_android_rgb16_force(),
+                             StaticPrefs::gfx_android_rgb16_force_AtStartup(),
                              0,  // SkiaGL canvas no longer supported
-                             StaticPrefs::layers_force_shmem_tiles());
+                             StaticPrefs::layers_force_shmem_tiles_AtStartup());
     ScopedGfxFeatureReporter::AppNote(forcedPrefs);
   }
 
   InitMoz2DLogging();
 
   gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock");
 
   /* Initialize the GfxInfo service.
@@ -1132,34 +1135,35 @@ bool gfxPlatform::IsDXP016Blocked() {
   return IsFeatureSupported(nsIGfxInfo::FEATURE_DX_P016);
 }
 
 /* static */
 int32_t gfxPlatform::MaxTextureSize() {
   // Make sure we don't completely break rendering because of a typo in the
   // pref or whatnot.
   const int32_t kMinSizePref = 2048;
-  return std::max(kMinSizePref,
-                  StaticPrefs::gfx_max_texture_size_DoNotUseDirectly());
+  return std::max(
+      kMinSizePref,
+      StaticPrefs::gfx_max_texture_size_AtStartup_DoNotUseDirectly());
 }
 
 /* static */
 int32_t gfxPlatform::MaxAllocSize() {
   // Make sure we don't completely break rendering because of a typo in the
   // pref or whatnot.
   const int32_t kMinAllocPref = 10000000;
   return std::max(kMinAllocPref,
-                  StaticPrefs::gfx_max_alloc_size_DoNotUseDirectly());
+                  StaticPrefs::gfx_max_alloc_size_AtStartup_DoNotUseDirectly());
 }
 
 /* static */
 void gfxPlatform::InitMoz2DLogging() {
   auto fwd = new CrashStatsLogForwarder(
       CrashReporter::Annotation::GraphicsCriticalError);
-  fwd->SetCircularBufferSize(StaticPrefs::gfx_logging_crash_length());
+  fwd->SetCircularBufferSize(StaticPrefs::gfx_logging_crash_length_AtStartup());
 
   mozilla::gfx::Config cfg;
   cfg.mLogForwarder = fwd;
   cfg.mMaxTextureSize = gfxPlatform::MaxTextureSize();
   cfg.mMaxAllocSize = gfxPlatform::MaxAllocSize();
 
   gfx::Factory::Init(cfg);
 }
@@ -1553,20 +1557,20 @@ already_AddRefed<DataSourceSurface> gfxP
 
 void gfxPlatform::ComputeTileSize() {
   // The tile size should be picked in the parent processes
   // and sent to the child processes over IPDL GetTileSize.
   if (!XRE_IsParentProcess()) {
     return;
   }
 
-  int32_t w = StaticPrefs::layers_tile_width();
-  int32_t h = StaticPrefs::layers_tile_height();
-
-  if (StaticPrefs::layers_tiles_adjust()) {
+  int32_t w = StaticPrefs::layers_tile_width_AtStartup();
+  int32_t h = StaticPrefs::layers_tile_height_AtStartup();
+
+  if (StaticPrefs::layers_tiles_adjust_AtStartup()) {
     gfx::IntSize screenSize = GetScreenSize();
     if (screenSize.width > 0) {
       // Choose a size so that there are between 2 and 4 tiles per screen width.
       // FIXME: we should probably make sure this is within the max texture
       // size, but I think everything should at least support 1024
       w = h = clamped(int32_t(RoundUpPow2(screenSize.width)) / 4, 256, 1024);
     }
   }
@@ -2427,17 +2431,17 @@ void gfxPlatform::InitAcceleration() {
   if (Preferences::GetBool("media.hardware-video-decoding.enabled", false) &&
 #ifdef XP_WIN
       Preferences::GetBool("media.wmf.dxva.enabled", true) &&
 #endif
       NS_SUCCEEDED(
           gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_HARDWARE_VIDEO_DECODING,
                                     discardFailureId, &status))) {
     if (status == nsIGfxInfo::FEATURE_STATUS_OK ||
-        StaticPrefs::media_hardware_video_decoding_force_enabled()) {
+        StaticPrefs::media_hardware_video_decoding_force_enabled_AtStartup()) {
       sLayersSupportsHardwareVideoDecoding = true;
     }
   }
 
   sLayersAccelerationPrefsInitialized = true;
 
   if (XRE_IsParentProcess()) {
     Preferences::RegisterCallbackAndCall(
@@ -2448,18 +2452,18 @@ void gfxPlatform::InitAcceleration() {
     gfxVars::SetRemoteCanvasEnabled(StaticPrefs::gfx_canvas_remote() &&
                                     gfxConfig::IsEnabled(Feature::GPU_PROCESS));
   }
 }
 
 void gfxPlatform::InitGPUProcessPrefs() {
   // We want to hide this from about:support, so only set a default if the
   // pref is known to be true.
-  if (!StaticPrefs::layers_gpu_process_enabled() &&
-      !StaticPrefs::layers_gpu_process_force_enabled()) {
+  if (!StaticPrefs::layers_gpu_process_enabled_AtStartup() &&
+      !StaticPrefs::layers_gpu_process_force_enabled_AtStartup()) {
     return;
   }
 
   FeatureState& gpuProc = gfxConfig::GetFeature(Feature::GPU_PROCESS);
 
   // We require E10S - otherwise, there is very little benefit to the GPU
   // process, since the UI process must still use acceleration for
   // performance.
@@ -2468,17 +2472,17 @@ void gfxPlatform::InitGPUProcessPrefs() 
                              "Multi-process mode is not enabled",
                              NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_E10S"));
   } else {
     gpuProc.SetDefaultFromPref(
         StaticPrefs::GetPrefName_layers_gpu_process_enabled(), true,
         StaticPrefs::GetPrefDefault_layers_gpu_process_enabled());
   }
 
-  if (StaticPrefs::layers_gpu_process_force_enabled()) {
+  if (StaticPrefs::layers_gpu_process_force_enabled_AtStartup()) {
     gpuProc.UserForceEnable("User force-enabled via pref");
   }
 
   if (IsHeadless()) {
     gpuProc.ForceDisable(FeatureStatus::Blocked, "Headless mode is enabled",
                          NS_LITERAL_CSTRING("FEATURE_FAILURE_HEADLESS_MODE"));
     return;
   }
@@ -2500,31 +2504,33 @@ void gfxPlatform::InitGPUProcessPrefs() 
 void gfxPlatform::InitCompositorAccelerationPrefs() {
   const char* acceleratedEnv = PR_GetEnv("MOZ_ACCELERATED");
 
   FeatureState& feature = gfxConfig::GetFeature(Feature::HW_COMPOSITING);
 
   // Base value - does the platform allow acceleration?
   if (feature.SetDefault(AccelerateLayersByDefault(), FeatureStatus::Blocked,
                          "Acceleration blocked by platform")) {
-    if (StaticPrefs::layers_acceleration_disabled_DoNotUseDirectly()) {
+    if (StaticPrefs::
+            layers_acceleration_disabled_AtStartup_DoNotUseDirectly()) {
       feature.UserDisable("Disabled by pref",
                           NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_PREF"));
     } else if (acceleratedEnv && *acceleratedEnv == '0') {
       feature.UserDisable("Disabled by envvar",
                           NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_ENV"));
     }
   } else {
     if (acceleratedEnv && *acceleratedEnv == '1') {
       feature.UserEnable("Enabled by envvar");
     }
   }
 
   // This has specific meaning elsewhere, so we always record it.
-  if (StaticPrefs::layers_acceleration_force_enabled_DoNotUseDirectly()) {
+  if (StaticPrefs::
+          layers_acceleration_force_enabled_AtStartup_DoNotUseDirectly()) {
     feature.UserForceEnable("Force-enabled by pref");
   }
 
   // Safe, headless, and record/replay modes override everything.
   if (InSafeMode()) {
     feature.ForceDisable(FeatureStatus::Blocked,
                          "Acceleration blocked by safe-mode",
                          NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_SAFEMODE"));
@@ -2538,18 +2544,18 @@ void gfxPlatform::InitCompositorAccelera
     feature.ForceDisable(
         FeatureStatus::Blocked, "Acceleration blocked by recording/replaying",
         NS_LITERAL_CSTRING("FEATURE_FAILURE_COMP_RECORDREPLAY"));
   }
 }
 
 /*static*/
 bool gfxPlatform::WebRenderPrefEnabled() {
-  return StaticPrefs::gfx_webrender_all() ||
-         StaticPrefs::gfx_webrender_enabled_DoNotUseDirectly();
+  return StaticPrefs::gfx_webrender_all_AtStartup() ||
+         StaticPrefs::gfx_webrender_enabled_AtStartup_DoNotUseDirectly();
 }
 
 /*static*/
 bool gfxPlatform::WebRenderEnvvarEnabled() {
   const char* env = PR_GetEnv("MOZ_WEBRENDER");
   return (env && *env == '1');
 }
 
@@ -2992,17 +2998,17 @@ void gfxPlatform::InitWebRenderConfig() 
     } else if (wrQualifiedAll) {
       featureWebRender.UserEnable("Qualified enabled by pref");
     }
   }
 
   // If the user set the pref to force-disable, let's do that. This will
   // override all the other enabling prefs (gfx.webrender.enabled,
   // gfx.webrender.all, and gfx.webrender.all.qualified).
-  if (StaticPrefs::gfx_webrender_force_disabled() ||
+  if (StaticPrefs::gfx_webrender_force_disabled_AtStartup() ||
       (WebRenderEnvvarDisabled() && !InMarionetteRolloutTest())) {
     featureWebRender.UserDisable(
         "User force-disabled WR",
         NS_LITERAL_CSTRING("FEATURE_FAILURE_USER_FORCE_DISABLED"));
   }
 
   // HW_COMPOSITING being disabled implies interfacing with the GPU might break
   if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) {
@@ -3072,17 +3078,17 @@ void gfxPlatform::InitWebRenderConfig() 
       // already have been forced disabled (e.g. safe mode, headless). It may
       // still be forced on by the user, and if so, this should have no effect.
       gfxConfig::Disable(Feature::HW_COMPOSITING, FeatureStatus::Blocked,
                          "Acceleration blocked by platform");
     }
 
     if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING) &&
         gfxConfig::IsEnabled(Feature::GPU_PROCESS) &&
-        !StaticPrefs::layers_gpu_process_allow_software()) {
+        !StaticPrefs::layers_gpu_process_allow_software_AtStartup()) {
       // We have neither WebRender nor OpenGL, we don't allow the GPU process
       // for basic compositor, and it wasn't disabled already.
       gfxConfig::Disable(Feature::GPU_PROCESS, FeatureStatus::Unavailable,
                          "Hardware compositing is unavailable.");
     }
   }
 #endif
 
@@ -3167,17 +3173,17 @@ bool gfxPlatform::AccelerateLayersByDefa
   return false;
 #endif
 }
 
 bool gfxPlatform::BufferRotationEnabled() {
   MutexAutoLock autoLock(*gGfxPlatformPrefsLock);
 
   return sBufferRotationCheckPref &&
-         StaticPrefs::layers_bufferrotation_enabled();
+         StaticPrefs::layers_bufferrotation_enabled_AtStartup();
 }
 
 void gfxPlatform::DisableBufferRotation() {
   MutexAutoLock autoLock(*gGfxPlatformPrefsLock);
 
   sBufferRotationCheckPref = false;
 }
 
@@ -3188,58 +3194,61 @@ bool gfxPlatform::UsesOffMainThreadCompo
   }
 
   static bool firstTime = true;
   static bool result = false;
 
   if (firstTime) {
     MOZ_ASSERT(sLayersAccelerationPrefsInitialized);
     result = gfxVars::BrowserTabsRemoteAutostart() ||
-             !StaticPrefs::layers_offmainthreadcomposition_force_disabled();
+             !StaticPrefs::
+                 layers_offmainthreadcomposition_force_disabled_AtStartup();
 #if defined(MOZ_WIDGET_GTK)
     // Linux users who chose OpenGL are being grandfathered in to OMTC
-    result |= StaticPrefs::layers_acceleration_force_enabled_DoNotUseDirectly();
+    result |= StaticPrefs::
+        layers_acceleration_force_enabled_AtStartup_DoNotUseDirectly();
 
 #endif
     firstTime = false;
   }
 
   return result;
 }
 
 bool gfxPlatform::UsesTiling() const {
   bool usesSkia = GetDefaultContentBackend() == BackendType::SKIA;
 
   // We can't just test whether the PaintThread is initialized here because
   // this function is used when initializing the PaintThread. So instead we
   // check the conditions that enable OMTP with parallel painting.
   bool usesPOMTP = XRE_IsContentProcess() && gfxVars::UseOMTP() &&
-                   (StaticPrefs::layers_omtp_paint_workers() == -1 ||
-                    StaticPrefs::layers_omtp_paint_workers() > 1);
-
-  return StaticPrefs::layers_enable_tiles() ||
-         (StaticPrefs::layers_enable_tiles_if_skia_pomtp() && usesSkia &&
-          usesPOMTP);
+                   (StaticPrefs::layers_omtp_paint_workers_AtStartup() == -1 ||
+                    StaticPrefs::layers_omtp_paint_workers_AtStartup() > 1);
+
+  return StaticPrefs::layers_enable_tiles_AtStartup() ||
+         (StaticPrefs::layers_enable_tiles_if_skia_pomtp_AtStartup() &&
+          usesSkia && usesPOMTP);
 }
 
 bool gfxPlatform::ContentUsesTiling() const {
   BackendPrefsData data = GetBackendPrefs();
   BackendType contentBackend = GetContentBackendPref(data.mContentBitmask);
   if (contentBackend == BackendType::NONE) {
     contentBackend = data.mContentDefault;
   }
 
   bool contentUsesSkia = contentBackend == BackendType::SKIA;
   bool contentUsesPOMTP =
-      gfxVars::UseOMTP() && (StaticPrefs::layers_omtp_paint_workers() == -1 ||
-                             StaticPrefs::layers_omtp_paint_workers() > 1);
-
-  return StaticPrefs::layers_enable_tiles() ||
-         (StaticPrefs::layers_enable_tiles_if_skia_pomtp() && contentUsesSkia &&
-          contentUsesPOMTP);
+      gfxVars::UseOMTP() &&
+      (StaticPrefs::layers_omtp_paint_workers_AtStartup() == -1 ||
+       StaticPrefs::layers_omtp_paint_workers_AtStartup() > 1);
+
+  return StaticPrefs::layers_enable_tiles_AtStartup() ||
+         (StaticPrefs::layers_enable_tiles_if_skia_pomtp_AtStartup() &&
+          contentUsesSkia && contentUsesPOMTP);
 }
 
 /***
  * The preference "layout.frame_rate" has 3 meanings depending on the value:
  *
  * -1 = Auto (default), use hardware vsync or software vsync @ 60 hz if hw
  *      vsync fails.
  *  0 = ASAP mode - used during talos testing.
@@ -3352,17 +3361,17 @@ void gfxPlatform::GetApzSupportInfo(mozi
   }
 
   if (SupportsApzAutoscrolling()) {
     aObj.DefineProperty("ApzAutoscrollInput", 1);
   }
 }
 
 void gfxPlatform::GetTilesSupportInfo(mozilla::widget::InfoObject& aObj) {
-  if (!StaticPrefs::layers_enable_tiles()) {
+  if (!StaticPrefs::layers_enable_tiles_AtStartup()) {
     return;
   }
 
   IntSize tileSize = gfxVars::TileSize();
   aObj.DefineProperty("TileHeight", tileSize.height);
   aObj.DefineProperty("TileWidth", tileSize.width);
 }
 
@@ -3432,17 +3441,17 @@ class FrameStatsComparator {
   // Reverse the condition here since we want the array sorted largest to
   // smallest.
   bool LessThan(const FrameStats& aA, const FrameStats& aB) const {
     return aA.contentFrameTime() > aB.contentFrameTime();
   }
 };
 
 void gfxPlatform::NotifyFrameStats(nsTArray<FrameStats>&& aFrameStats) {
-  if (!StaticPrefs::gfx_logging_slow_frames_enabled()) {
+  if (!StaticPrefs::gfx_logging_slow_frames_enabled_AtStartup()) {
     return;
   }
 
   FrameStatsComparator comp;
   for (FrameStats& f : aFrameStats) {
     mFrameStats.InsertElementSorted(f, comp);
   }
   if (mFrameStats.Length() > 10) {
@@ -3468,17 +3477,18 @@ bool gfxPlatform::AsyncPanZoomEnabled() 
   // this requirement.
   if (!BrowserTabsRemoteAutostart()) {
     return false;
   }
 #endif
 #ifdef MOZ_WIDGET_ANDROID
   return true;
 #else
-  return StaticPrefs::layers_async_pan_zoom_enabled_DoNotUseDirectly();
+  return StaticPrefs::
+      layers_async_pan_zoom_enabled_AtStartup_DoNotUseDirectly();
 #endif
 }
 
 /*static*/
 bool gfxPlatform::PerfWarnings() {
   return StaticPrefs::gfx_perf_warnings_enabled();
 }
 
@@ -3593,17 +3603,17 @@ bool gfxPlatform::SupportsApzTouchInput(
   return dom::TouchEvent::PrefEnabled(nullptr);
 }
 
 bool gfxPlatform::SupportsApzDragInput() const {
   return StaticPrefs::apz_drag_enabled();
 }
 
 bool gfxPlatform::SupportsApzKeyboardInput() const {
-  return StaticPrefs::apz_keyboard_enabled();
+  return StaticPrefs::apz_keyboard_enabled_AtStartup();
 }
 
 bool gfxPlatform::SupportsApzAutoscrolling() const {
   return StaticPrefs::apz_autoscroll_enabled();
 }
 
 void gfxPlatform::InitOpenGLConfig() {
 #ifdef XP_WIN
@@ -3630,17 +3640,18 @@ void gfxPlatform::InitOpenGLConfig() {
       StaticPrefs::GetPrefName_layers_prefer_opengl(), true,
       StaticPrefs::GetPrefDefault_layers_prefer_opengl());
 #else
   openGLFeature.EnableByDefault();
 #endif
 
   // When layers acceleration is force-enabled, enable it even for blacklisted
   // devices.
-  if (StaticPrefs::layers_acceleration_force_enabled_DoNotUseDirectly()) {
+  if (StaticPrefs::
+          layers_acceleration_force_enabled_AtStartup_DoNotUseDirectly()) {
     openGLFeature.UserForceEnable("Force-enabled by pref");
     return;
   }
 
   nsCString message;
   nsCString failureId;
   if (!IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_OPENGL_LAYERS, &message,
                            failureId)) {
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -420,17 +420,18 @@ nsresult gfxPlatformFontList::InitFontLi
   mCodepointsWithNoFonts.reset();
   mCodepointsWithNoFonts.SetRange(0, 0x1f);     // C0 controls
   mCodepointsWithNoFonts.SetRange(0x7f, 0x9f);  // C1 controls
 
   sPlatformFontList = this;
 
   // Try to initialize the cross-process shared font list if enabled by prefs,
   // but not if we're running in Safe Mode.
-  if (StaticPrefs::gfx_e10s_font_list_shared() && !gfxPlatform::InSafeMode()) {
+  if (StaticPrefs::gfx_e10s_font_list_shared_AtStartup() &&
+      !gfxPlatform::InSafeMode()) {
     for (auto i = mFontEntries.Iter(); !i.Done(); i.Next()) {
       i.Data()->mShmemCharacterMap = nullptr;
       i.Data()->mShmemFace = nullptr;
       i.Data()->mFamilyName = NS_LITERAL_CSTRING("");
     }
     mFontEntries.Clear();
     mShmemCharMaps.Clear();
     bool oldSharedList = mSharedFontList != nullptr;
--- a/gfx/thebes/gfxPlatformGtk.cpp
+++ b/gfx/thebes/gfxPlatformGtk.cpp
@@ -297,17 +297,17 @@ double gfxPlatformGtk::GetFontScaleFacto
   if (dpi < 168) {
     return 1.5;
   }
   return round(dpi / 96.0);
 }
 
 bool gfxPlatformGtk::UseImageOffscreenSurfaces() {
   return GetDefaultContentBackend() != mozilla::gfx::BackendType::CAIRO ||
-         StaticPrefs::layers_use_image_offscreen_surfaces();
+         StaticPrefs::layers_use_image_offscreen_surfaces_AtStartup();
 }
 
 gfxImageFormat gfxPlatformGtk::GetOffscreenFormat() {
   // Make sure there is a screen
   GdkScreen* screen = gdk_screen_get_default();
   if (screen && gdk_visual_get_depth(gdk_visual_get_system()) == 16) {
     return SurfaceFormat::R5G6B5_UINT16;
   }
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -1465,25 +1465,25 @@ bool gfxUtils::DumpDisplayList() {
          (StaticPrefs::layout_display_list_dump_parent() &&
           XRE_IsParentProcess()) ||
          (StaticPrefs::layout_display_list_dump_content() &&
           XRE_IsContentProcess());
 }
 
 wr::RenderRoot gfxUtils::GetContentRenderRoot() {
   if (gfx::gfxVars::UseWebRender() &&
-      StaticPrefs::gfx_webrender_split_render_roots()) {
+      StaticPrefs::gfx_webrender_split_render_roots_AtStartup()) {
     return wr::RenderRoot::Content;
   }
   return wr::RenderRoot::Default;
 }
 
 Maybe<wr::RenderRoot> gfxUtils::GetRenderRootForFrame(const nsIFrame* aFrame) {
   if (!gfxVars::UseWebRender() ||
-      !StaticPrefs::gfx_webrender_split_render_roots() ||
+      !StaticPrefs::gfx_webrender_split_render_roots_AtStartup() ||
       !XRE_IsParentProcess()) {
     return Nothing();
   }
   if (!aFrame->GetContent()) {
     return Nothing();
   }
   if (!aFrame->GetContent()->IsElement()) {
     return Nothing();
@@ -1498,17 +1498,17 @@ Maybe<wr::RenderRoot> gfxUtils::GetRende
     return Some(wr::RenderRoot::Popover);
   }
   return Nothing();
 }
 
 wr::RenderRoot gfxUtils::RecursivelyGetRenderRootForFrame(
     const nsIFrame* aFrame) {
   if (!gfxVars::UseWebRender() ||
-      !StaticPrefs::gfx_webrender_split_render_roots() ||
+      !StaticPrefs::gfx_webrender_split_render_roots_AtStartup() ||
       !XRE_IsParentProcess()) {
     return wr::RenderRoot::Default;
   }
 
   for (const nsIFrame* current = aFrame; current;
        current = nsLayoutUtils::GetCrossDocParentFrame(current)) {
     auto renderRoot = gfxUtils::GetRenderRootForFrame(current);
     if (renderRoot) {
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -1362,41 +1362,41 @@ void gfxWindowsPlatform::InitializeD3D11
   nsCString message;
   nsCString failureId;
   if (!gfxPlatform::IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS,
                                         &message, failureId)) {
     d3d11.Disable(FeatureStatus::Blacklisted, message.get(), failureId);
   }
 
   // Check if the user really, really wants WARP.
-  if (StaticPrefs::layers_d3d11_force_warp()) {
+  if (StaticPrefs::layers_d3d11_force_warp_AtStartup()) {
     // Force D3D11 on even if we disabled it.
     d3d11.UserForceEnable("User force-enabled WARP");
   }
 
   InitializeAdvancedLayersConfig();
 }
 
 /* static */
 void gfxWindowsPlatform::InitializeAdvancedLayersConfig() {
   // Only enable Advanced Layers if D3D11 succeeded.
   if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
     return;
   }
 
   FeatureState& al = gfxConfig::GetFeature(Feature::ADVANCED_LAYERS);
   al.SetDefaultFromPref(
-      StaticPrefs::GetPrefName_layers_mlgpu_enabled_DoNotUseDirectly(),
+      StaticPrefs::GetPrefName_layers_mlgpu_enabled(),
       true /* aIsEnablePref */,
-      StaticPrefs::GetPrefDefault_layers_mlgpu_enabled_DoNotUseDirectly());
+      StaticPrefs::GetPrefDefault_layers_mlgpu_enabled());
 
   // Windows 7 has an extra pref since it uses totally different buffer paths
   // that haven't been performance tested yet.
   if (al.IsEnabled() && !IsWin8OrLater()) {
-    if (StaticPrefs::layers_mlgpu_enable_on_windows7()) {
+    if (StaticPrefs::layers_mlgpu_enable_on_windows7_AtStartup()) {
       al.UserEnable("Enabled for Windows 7 via user-preference");
     } else {
       al.Disable(FeatureStatus::Disabled,
                  "Advanced Layers is disabled on Windows 7 by default",
                  NS_LITERAL_CSTRING("FEATURE_FAILURE_DISABLED_ON_WIN7"));
     }
   }
 
@@ -1538,28 +1538,29 @@ void gfxWindowsPlatform::InitializeD2DCo
 
   if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
     d2d1.DisableByDefault(FeatureStatus::Unavailable,
                           "Direct2D requires Direct3D 11 compositing",
                           NS_LITERAL_CSTRING("FEATURE_FAILURE_D2D_D3D11_COMP"));
     return;
   }
 
-  d2d1.SetDefaultFromPref(StaticPrefs::GetPrefName_gfx_direct2d_disabled(),
-                          false,
-                          StaticPrefs::GetPrefDefault_gfx_direct2d_disabled());
+  d2d1.SetDefaultFromPref(
+      StaticPrefs::GetPrefName_gfx_direct2d_disabled(), false,
+      StaticPrefs::GetPrefDefault_gfx_direct2d_disabled());
 
   nsCString message;
   nsCString failureId;
   if (!gfxPlatform::IsGfxInfoStatusOkay(nsIGfxInfo::FEATURE_DIRECT2D, &message,
                                         failureId)) {
     d2d1.Disable(FeatureStatus::Blacklisted, message.get(), failureId);
   }
 
-  if (!d2d1.IsEnabled() && StaticPrefs::gfx_direct2d_force_enabled()) {
+  if (!d2d1.IsEnabled() &&
+      StaticPrefs::gfx_direct2d_force_enabled_AtStartup()) {
     d2d1.UserForceEnable("Force-enabled via user-preference");
   }
 }
 
 void gfxWindowsPlatform::InitializeD2D() {
   ScopedGfxFeatureReporter d2d1_1("D2D1.1");
 
   FeatureState& d2d1 = gfxConfig::GetFeature(Feature::DIRECT2D);
@@ -1633,17 +1634,17 @@ bool gfxWindowsPlatform::InitGPUProcessS
                                         &message, failureId)) {
     gpuProc.Disable(FeatureStatus::Blacklisted, message.get(), failureId);
     return false;
   }
 
   if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
     // Don't use the GPU process if not using D3D11, unless software
     // compositor is allowed
-    if (StaticPrefs::layers_gpu_process_allow_software()) {
+    if (StaticPrefs::layers_gpu_process_allow_software_AtStartup()) {
       return gpuProc.IsEnabled();
     }
     gpuProc.Disable(FeatureStatus::Unavailable,
                     "Not using GPU Process since D3D11 is unavailable",
                     NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_D3D11"));
   } else if (!IsWin7SP1OrLater()) {
     // On Windows 7 Pre-SP1, DXGI 1.2 is not available and remote presentation
     // for D3D11 will not work. Rather than take a regression we revert back
@@ -1940,17 +1941,17 @@ gfxWindowsPlatform::CreateHardwareVsyncS
 
   RefPtr<VsyncSource> d3dVsyncSource = new D3DVsyncSource();
   return d3dVsyncSource.forget();
 }
 
 void gfxWindowsPlatform::GetAcceleratedCompositorBackends(
     nsTArray<LayersBackend>& aBackends) {
   if (gfxConfig::IsEnabled(Feature::OPENGL_COMPOSITING) &&
-      StaticPrefs::layers_prefer_opengl()) {
+      StaticPrefs::layers_prefer_opengl_AtStartup()) {
     aBackends.AppendElement(LayersBackend::LAYERS_OPENGL);
   }
 
   if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
     aBackends.AppendElement(LayersBackend::LAYERS_D3D11);
   }
 }
 
--- a/gfx/vr/VRManager.cpp
+++ b/gfx/vr/VRManager.cpp
@@ -148,17 +148,17 @@ VRManager::VRManager()
   MOZ_COUNT_CTOR(VRManager);
   MOZ_ASSERT(sVRManagerSingleton == nullptr);
   MOZ_ASSERT(NS_IsMainThread());
 
 #if !defined(MOZ_WIDGET_ANDROID)
   // XRE_IsGPUProcess() is helping us to check some platforms like
   // Win 7 try which are not using GPU process but VR process is enabled.
   mVRProcessEnabled =
-      StaticPrefs::dom_vr_process_enabled() && XRE_IsGPUProcess();
+      StaticPrefs::dom_vr_process_enabled_AtStartup() && XRE_IsGPUProcess();
   VRServiceHost::Init(mVRProcessEnabled);
   mServiceHost = VRServiceHost::Get();
   // We must shutdown before VRServiceHost, which is cleared
   // on ShutdownPhase::ShutdownFinal, potentially before VRManager.
   // We hold a reference to VRServiceHost to ensure it stays
   // alive until we have shut down.
 #endif  // !defined(MOZ_WIDGET_ANDROID)
 }
--- a/gfx/vr/ipc/VRProcessManager.cpp
+++ b/gfx/vr/ipc/VRProcessManager.cpp
@@ -64,17 +64,17 @@ void VRProcessManager::LaunchVRProcess()
   // acquire the IPDL actor.
   mProcess = new VRProcessParent(this);
   if (!mProcess->Launch()) {
     DisableVRProcess("Failed to launch VR process");
   }
 }
 
 void VRProcessManager::DisableVRProcess(const char* aMessage) {
-  if (!StaticPrefs::dom_vr_process_enabled()) {
+  if (!StaticPrefs::dom_vr_process_enabled_AtStartup()) {
     return;
   }
 
   DestroyProcess();
 }
 
 void VRProcessManager::DestroyProcess() {
   if (!mProcess) {
--- a/gfx/vr/ipc/VRProcessParent.cpp
+++ b/gfx/vr/ipc/VRProcessParent.cpp
@@ -76,17 +76,18 @@ bool VRProcessParent::Launch() {
   return true;
 }
 
 bool VRProcessParent::WaitForLaunch() {
   if (mLaunchPhase == LaunchPhase::Complete) {
     return !!mVRChild;
   }
 
-  int32_t timeoutMs = StaticPrefs::dom_vr_process_startup_timeout_ms();
+  int32_t timeoutMs =
+      StaticPrefs::dom_vr_process_startup_timeout_ms_AtStartup();
 
   // If one of the following environment variables are set we can effectively
   // ignore the timeout - as we can guarantee the compositor process will be
   // terminated
   if (PR_GetEnv("MOZ_DEBUG_CHILD_PROCESS") ||
       PR_GetEnv("MOZ_DEBUG_CHILD_PAUSE")) {
     timeoutMs = 0;
   }
--- a/gfx/vr/service/OSVRSession.cpp
+++ b/gfx/vr/service/OSVRSession.cpp
@@ -204,17 +204,18 @@ OSVRSession::OSVRSession()
       mDisplayConfigInitialized(false),
       mInterfaceInitialized(false),
       m_ctx(nullptr),
       m_iface(nullptr),
       m_display(nullptr) {}
 OSVRSession::~OSVRSession() { Shutdown(); }
 
 bool OSVRSession::Initialize(mozilla::gfx::VRSystemState& aSystemState) {
-  if (!StaticPrefs::dom_vr_enabled() || !StaticPrefs::dom_vr_osvr_enabled()) {
+  if (!StaticPrefs::dom_vr_enabled() ||
+      !StaticPrefs::dom_vr_osvr_enabled_AtStartup()) {
     return false;
   }
   if (mOSVRInitialized) {
     return true;
   }
   if (!LoadOSVRRuntime()) {
     return false;
   }
--- a/gfx/vr/service/OculusSession.cpp
+++ b/gfx/vr/service/OculusSession.cpp
@@ -201,17 +201,18 @@ OculusSession::OculusSession()
       mInputLayout(nullptr),
       mRemainingVibrateTime{},
       mHapticPulseIntensity{},
       mIsPresenting(false) {}
 
 OculusSession::~OculusSession() { Shutdown(); }
 
 bool OculusSession::Initialize(mozilla::gfx::VRSystemState& aSystemState) {
-  if (!StaticPrefs::dom_vr_enabled() || !StaticPrefs::dom_vr_oculus_enabled()) {
+  if (!StaticPrefs::dom_vr_enabled() ||
+      !StaticPrefs::dom_vr_oculus_enabled_AtStartup()) {
     return false;
   }
 
   if (!CreateD3DObjects()) {
     return false;
   }
   if (!CreateShaders()) {
     return false;
--- a/gfx/vr/service/OpenVRSession.cpp
+++ b/gfx/vr/service/OpenVRSession.cpp
@@ -247,17 +247,18 @@ OpenVRSession::OpenVRSession()
 }
 
 OpenVRSession::~OpenVRSession() {
   mActionsetFirefox = ::vr::k_ulInvalidActionSetHandle;
   Shutdown();
 }
 
 bool OpenVRSession::Initialize(mozilla::gfx::VRSystemState& aSystemState) {
-  if (!StaticPrefs::dom_vr_enabled() || !StaticPrefs::dom_vr_openvr_enabled()) {
+  if (!StaticPrefs::dom_vr_enabled() ||
+      !StaticPrefs::dom_vr_openvr_enabled_AtStartup()) {
     return false;
   }
   if (mVRSystem != nullptr) {
     // Already initialized
     return true;
   }
   if (!::vr::VR_IsRuntimeInstalled()) {
     return false;
@@ -303,17 +304,18 @@ bool OpenVRSession::Initialize(mozilla::
   // Configure coordinate system
   mVRCompositor->SetTrackingSpace(::vr::TrackingUniverseSeated);
 
   if (!InitState(aSystemState)) {
     Shutdown();
     return false;
   }
 
-  if (StaticPrefs::dom_vr_openvr_action_input() && !SetupContollerActions()) {
+  if (StaticPrefs::dom_vr_openvr_action_input_AtStartup() &&
+      !SetupContollerActions()) {
     return false;
   }
 
   NS_DispatchToMainThread(NS_NewRunnableFunction(
       "OpenVRSession::StartHapticThread", [this]() { StartHapticThread(); }));
 
   // Succeeded
   return true;
@@ -329,17 +331,17 @@ bool OpenVRSession::SetupContollerAction
   // If it didn't exist yet, create a new temp file.
   nsCString controllerAction;
   nsCString viveManifest;
   nsCString WMRManifest;
   nsCString knucklesManifest;
   nsCString cosmosManifest;
 
   // Getting / Generating manifest file paths.
-  if (StaticPrefs::dom_vr_process_enabled()) {
+  if (StaticPrefs::dom_vr_process_enabled_AtStartup()) {
     VRParent* vrParent = VRProcessChild::GetVRParent();
     nsCString output;
 
     if (vrParent->GetOpenVRControllerActionPath(&output)) {
       controllerAction = output;
     }
 
     if (vrParent->GetOpenVRControllerManifestPath(OpenVRControllerType::Vive,
@@ -826,17 +828,17 @@ bool OpenVRSession::SetupContollerAction
       vr::VRInput()->SetActionManifestPath(controllerAction.BeginReading());
   if (err != vr::VRInputError_None) {
     NS_WARNING("OpenVR - SetActionManifestPath failed.");
     return false;
   }
   // End of setup controller actions.
 
   // Notify the parent process these manifest files are already been recorded.
-  if (StaticPrefs::dom_vr_process_enabled()) {
+  if (StaticPrefs::dom_vr_process_enabled_AtStartup()) {
     NS_DispatchToMainThread(NS_NewRunnableFunction(
         "SendOpenVRControllerActionPathToParent",
         [controllerAction, viveManifest, WMRManifest, knucklesManifest,
          cosmosManifest]() {
           VRParent* vrParent = VRProcessChild::GetVRParent();
           Unused << vrParent->SendOpenVRControllerActionPathToParent(
               controllerAction);
           Unused << vrParent->SendOpenVRControllerManifestPathToParent(
@@ -2022,17 +2024,17 @@ void OpenVRSession::GetControllerDeviceI
       break;
   }
 }
 
 void OpenVRSession::StartFrame(mozilla::gfx::VRSystemState& aSystemState) {
   UpdateHeadsetPose(aSystemState);
   UpdateEyeParameters(aSystemState);
 
-  if (StaticPrefs::dom_vr_openvr_action_input()) {
+  if (StaticPrefs::dom_vr_openvr_action_input_AtStartup()) {
     EnumerateControllers(aSystemState);
 
     vr::VRActiveActionSet_t actionSet = {0};
     actionSet.ulActionSet = mActionsetFirefox;
     vr::VRInput()->UpdateActionState(&actionSet, sizeof(actionSet), 1);
 
     UpdateControllerButtons(aSystemState);
     UpdateControllerPoses(aSystemState);
@@ -2234,17 +2236,17 @@ void OpenVRSession::HapticTimerCallback(
   /**
    * It is safe to use the pointer passed in aClosure to reference the
    * OpenVRSession object as the timer is canceled in OpenVRSession::Shutdown,
    * which is called by the OpenVRSession destructor, guaranteeing
    * that this function runs if and only if the VRManager object is valid.
    */
   OpenVRSession* self = static_cast<OpenVRSession*>(aClosure);
 
-  if (StaticPrefs::dom_vr_openvr_action_input()) {
+  if (StaticPrefs::dom_vr_openvr_action_input_AtStartup()) {
     self->UpdateHaptics();
   } else {
     self->UpdateHapticsObsolete();
   }
 }
 
 void OpenVRSession::UpdateHaptics() {
   MOZ_ASSERT(mHapticThread->GetThread() == NS_GetCurrentThread());
--- a/gfx/webrender_bindings/RenderCompositorOGL.cpp
+++ b/gfx/webrender_bindings/RenderCompositorOGL.cpp
@@ -69,17 +69,17 @@ void RenderCompositorOGL::EndFrame() {
   InsertFrameDoneSync();
   mGL->SwapBuffers();
 }
 
 void RenderCompositorOGL::InsertFrameDoneSync() {
 #ifdef XP_MACOSX
   // Only do this on macOS.
   // On other platforms, SwapBuffers automatically applies back-pressure.
-  if (StaticPrefs::gfx_core_animation_enabled()) {
+  if (StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
     if (mThisFrameDoneSync) {
       mGL->fDeleteSync(mThisFrameDoneSync);
     }
     mThisFrameDoneSync =
         mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
   }
 #endif
 }
--- a/image/AnimationSurfaceProvider.cpp
+++ b/image/AnimationSurfaceProvider.cpp
@@ -403,17 +403,17 @@ void AnimationSurfaceProvider::RequestFr
     MOZ_ASSERT_UNREACHABLE("Already replaced frame queue!");
     return;
   }
 
   auto oldFrameQueue =
       static_cast<AnimationFrameRetainedBuffer*>(mFrames.get());
 
   MOZ_ASSERT(!mDecoder->GetFrameRecycler());
-  if (StaticPrefs::image_animated_decode_on_demand_recycle()) {
+  if (StaticPrefs::image_animated_decode_on_demand_recycle_AtStartup()) {
     mFrames.reset(new AnimationFrameRecyclingQueue(std::move(*oldFrameQueue)));
     mDecoder->SetFrameRecycler(this);
   } else {
     mFrames.reset(new AnimationFrameDiscardingQueue(std::move(*oldFrameQueue)));
   }
 }
 
 void AnimationSurfaceProvider::AnnounceSurfaceAvailable() {
@@ -461,17 +461,17 @@ void AnimationSurfaceProvider::FinishDec
   DropImageReference();
 }
 
 bool AnimationSurfaceProvider::ShouldPreferSyncRun() const {
   MutexAutoLock lock(mDecodingMutex);
   MOZ_ASSERT(mDecoder);
 
   return mDecoder->ShouldSyncDecode(
-      StaticPrefs::image_mem_decode_bytes_at_a_time());
+      StaticPrefs::image_mem_decode_bytes_at_a_time_AtStartup());
 }
 
 RawAccessFrameRef AnimationSurfaceProvider::RecycleFrame(
     gfx::IntRect& aRecycleRect) {
   MutexAutoLock lock(mFramesMutex);
   MOZ_ASSERT(mFrames->IsRecycling());
   return mFrames->RecycleFrame(aRecycleRect);
 }
--- a/image/DecodePool.cpp
+++ b/image/DecodePool.cpp
@@ -349,17 +349,18 @@ class IOThreadIniter final : public Runn
 
     return NS_OK;
   }
 };
 #endif
 
 DecodePool::DecodePool() : mMutex("image::IOThread") {
   // Determine the number of threads we want.
-  int32_t prefLimit = StaticPrefs::image_multithreaded_decoding_limit();
+  int32_t prefLimit =
+      StaticPrefs::image_multithreaded_decoding_limit_AtStartup();
   uint32_t limit;
   if (prefLimit <= 0) {
     int32_t numCores = NumberOfCores();
     if (numCores <= 1) {
       limit = 1;
     } else if (numCores == 2) {
       // On an otherwise mostly idle system, having two image decoding threads
       // doubles decoding performance, so it's worth doing on dual-core devices,
@@ -380,17 +381,17 @@ DecodePool::DecodePool() : mMutex("image
     limit = 4;
   }
 
   // The maximum number of idle threads allowed.
   uint32_t idleLimit;
 
   // The timeout period before shutting down idle threads.
   int32_t prefIdleTimeout =
-      StaticPrefs::image_multithreaded_decoding_idle_timeout();
+      StaticPrefs::image_multithreaded_decoding_idle_timeout_AtStartup();
   TimeDuration idleTimeout;
   if (prefIdleTimeout <= 0) {
     idleTimeout = TimeDuration::Forever();
     idleLimit = limit;
   } else {
     idleTimeout = TimeDuration::FromMilliseconds(prefIdleTimeout);
     idleLimit = (limit + 1) / 2;
   }
--- a/image/DecodedSurfaceProvider.cpp
+++ b/image/DecodedSurfaceProvider.cpp
@@ -196,13 +196,13 @@ void DecodedSurfaceProvider::FinishDecod
   // keeping it alive as long as we remain in the surface cache, which could
   // greatly extend the image's lifetime - in fact, if the image isn't
   // discardable, it'd result in a leak!
   DropImageReference();
 }
 
 bool DecodedSurfaceProvider::ShouldPreferSyncRun() const {
   return mDecoder->ShouldSyncDecode(
-      StaticPrefs::image_mem_decode_bytes_at_a_time());
+      StaticPrefs::image_mem_decode_bytes_at_a_time_AtStartup());
 }
 
 }  // namespace image
 }  // namespace mozilla
--- a/image/FrameAnimator.cpp
+++ b/image/FrameAnimator.cpp
@@ -81,17 +81,17 @@ const gfx::IntRect AnimationState::Updat
       if (mCompositedFrameInvalid) {
         // Invalidate if we are marking the composited frame valid.
         ret.SizeTo(aSize);
       }
       mCompositedFrameInvalid = false;
     } else if (aResult.Type() == MatchType::NOT_FOUND ||
                aResult.Type() == MatchType::PENDING) {
       if (mHasRequestedDecode) {
-        MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable());
+        MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
         mCompositedFrameInvalid = true;
       }
     }
     // Otherwise don't change the value of mCompositedFrameInvalid, it will be
     // updated by RequestRefresh.
   }
 
   return ret;
@@ -374,17 +374,17 @@ RefreshResult FrameAnimator::RequestRefr
   }
 
   RefPtr<imgFrame> currentFrame =
       result.Surface().GetFrame(aState.mCurrentAnimationFrameIndex);
 
   // only advance the frame if the current time is greater than or
   // equal to the current frame's end time.
   if (!currentFrame) {
-    MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable());
+    MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
     MOZ_ASSERT(aState.GetHasRequestedDecode() &&
                !aState.GetIsCurrentlyDecoded());
     MOZ_ASSERT(aState.mCompositedFrameInvalid);
     // Nothing we can do but wait for our previous current frame to be decoded
     // again so we can determine what to do next.
     aState.MaybeAdvanceAnimationFrameTime(aTime);
     return ret;
   }
@@ -446,17 +446,17 @@ LookupResult FrameAnimator::GetComposite
   aState.mCompositedFrameRequested = true;
 
   LookupResult result = SurfaceCache::Lookup(
       ImageKey(mImage),
       RasterSurfaceKey(mSize, DefaultSurfaceFlags(), PlaybackType::eAnimated),
       aMarkUsed);
 
   if (aState.mCompositedFrameInvalid) {
-    MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable());
+    MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
     MOZ_ASSERT(aState.GetHasRequestedDecode());
     MOZ_ASSERT(!aState.GetIsCurrentlyDecoded());
     if (result.Type() == MatchType::NOT_FOUND) {
       return result;
     }
     return LookupResult(MatchType::PENDING);
   }
 
--- a/image/FrameAnimator.h
+++ b/image/FrameAnimator.h
@@ -75,17 +75,18 @@ class AnimationState {
    * been created to redecode it.
    */
   bool IsDiscarded() { return mDiscarded; }
 
   /**
    * Sets the composited frame as valid or invalid.
    */
   void SetCompositedFrameInvalid(bool aInvalid) {
-    MOZ_ASSERT(!aInvalid || StaticPrefs::image_mem_animated_discardable());
+    MOZ_ASSERT(!aInvalid ||
+               StaticPrefs::image_mem_animated_discardable_AtStartup());
     mCompositedFrameInvalid = aInvalid;
   }
 
   /**
    * Returns whether the composited frame is valid to draw to the screen.
    */
   bool GetCompositedFrameInvalid() { return mCompositedFrameInvalid; }
 
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -342,17 +342,17 @@ LookupResult RasterImage::LookupFrame(co
   if (result.Type() == MatchType::NOT_FOUND ||
       (result.Type() == MatchType::SUBSTITUTE_BECAUSE_NOT_FOUND &&
        !avoidRedecode) ||
       (syncDecode && !avoidRedecode && !result)) {
     // We don't have a copy of this frame, and there's no decoder working on
     // one. (Or we're sync decoding and the existing decoder hasn't even started
     // yet.) Trigger decoding so it'll be available next time.
     MOZ_ASSERT(aPlaybackType != PlaybackType::eAnimated ||
-                   StaticPrefs::image_mem_animated_discardable() ||
+                   StaticPrefs::image_mem_animated_discardable_AtStartup() ||
                    !mAnimationState || mAnimationState->KnownFrameCount() < 1,
                "Animated frames should be locked");
 
     // The surface cache may suggest the preferred size we are supposed to
     // decode at. This should only happen if we accept substitutions.
     if (!result.SuggestedSize().IsEmpty()) {
       MOZ_ASSERT(!syncDecode && (aFlags & FLAG_HIGH_QUALITY_SCALING));
       requestedSize = result.SuggestedSize();
@@ -410,17 +410,17 @@ bool RasterImage::IsOpaque() {
 
 NS_IMETHODIMP_(bool)
 RasterImage::WillDrawOpaqueNow() {
   if (!IsOpaque()) {
     return false;
   }
 
   if (mAnimationState) {
-    if (!StaticPrefs::image_mem_animated_discardable()) {
+    if (!StaticPrefs::image_mem_animated_discardable_AtStartup()) {
       // We never discard frames of animated images.
       return true;
     } else {
       if (mAnimationState->GetCompositedFrameInvalid()) {
         // We're not going to draw anything at all.
         return false;
       }
     }
@@ -466,17 +466,17 @@ void RasterImage::OnSurfaceDiscarded(con
       });
   eventTarget->Dispatch(ev.forget(), NS_DISPATCH_NORMAL);
 }
 
 void RasterImage::OnSurfaceDiscardedInternal(bool aAnimatedFramesDiscarded) {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (aAnimatedFramesDiscarded && mAnimationState) {
-    MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable());
+    MOZ_ASSERT(StaticPrefs::image_mem_animated_discardable_AtStartup());
     ReleaseImageContainer();
     gfx::IntRect rect =
         mAnimationState->UpdateState(mAnimationFinished, this, mSize);
     NotifyProgress(NoProgress, rect);
   }
 
   if (mProgressTracker) {
     mProgressTracker->OnDiscard();
@@ -711,17 +711,17 @@ bool RasterImage::SetMetadata(const Imag
     mHasSize = true;
   }
 
   if (mHasSize && aMetadata.HasAnimation() && !mAnimationState) {
     // We're becoming animated, so initialize animation stuff.
     mAnimationState.emplace(mAnimationMode);
     mFrameAnimator = MakeUnique<FrameAnimator>(this, mSize);
 
-    if (!StaticPrefs::image_mem_animated_discardable()) {
+    if (!StaticPrefs::image_mem_animated_discardable_AtStartup()) {
       // We don't support discarding animated images (See bug 414259).
       // Lock the image and throw away the key.
       LockImage();
     }
 
     if (!aFromMetadataDecode) {
       // The metadata decode reported that this image isn't animated, but we
       // discovered that it actually was during the full decode. This is a
@@ -1015,17 +1015,18 @@ RasterImage::GetKeys(nsTArray<nsCString>
     return NS_OK;
   }
   return mProperties->GetKeys(keys);
 }
 
 void RasterImage::Discard() {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(CanDiscard(), "Asked to discard but can't");
-  MOZ_ASSERT(!mAnimationState || StaticPrefs::image_mem_animated_discardable(),
+  MOZ_ASSERT(!mAnimationState ||
+                 StaticPrefs::image_mem_animated_discardable_AtStartup(),
              "Asked to discard for animated image");
 
   // Delete all the decoded frames.
   SurfaceCache::RemoveImage(ImageKey(this));
 
   if (mAnimationState) {
     ReleaseImageContainer();
     gfx::IntRect rect =
@@ -1037,17 +1038,18 @@ void RasterImage::Discard() {
   if (mProgressTracker) {
     mProgressTracker->OnDiscard();
   }
 }
 
 bool RasterImage::CanDiscard() {
   return mAllSourceData &&
          // Can discard animated images if the pref is set
-         (!mAnimationState || StaticPrefs::image_mem_animated_discardable());
+         (!mAnimationState ||
+          StaticPrefs::image_mem_animated_discardable_AtStartup());
 }
 
 NS_IMETHODIMP
 RasterImage::StartDecoding(uint32_t aFlags, uint32_t aWhichFrame) {
   if (mError) {
     return NS_ERROR_FAILURE;
   }
 
--- a/image/SurfaceCache.cpp
+++ b/image/SurfaceCache.cpp
@@ -1049,20 +1049,20 @@ class SurfaceCacheImpl final : public ns
                      const StaticMutexAutoLock& aAutoLock) {
     RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
     if (!cache || !cache->IsLocked()) {
       return;  // Already unlocked.
     }
 
     // (Note that we *don't* unlock the per-image cache here; that's the
     // difference between this and UnlockImage.)
-    DoUnlockSurfaces(
-        WrapNotNull(cache),
-        /* aStaticOnly = */ !StaticPrefs::image_mem_animated_discardable(),
-        aAutoLock);
+    DoUnlockSurfaces(WrapNotNull(cache),
+                     /* aStaticOnly = */
+                     !StaticPrefs::image_mem_animated_discardable_AtStartup(),
+                     aAutoLock);
   }
 
   already_AddRefed<ImageSurfaceCache> RemoveImage(
       const ImageKey aImageKey, const StaticMutexAutoLock& aAutoLock) {
     RefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
     if (!cache) {
       return nullptr;  // No cached surfaces for this image, so nothing to do.
     }
@@ -1373,39 +1373,39 @@ void SurfaceCache::Initialize() {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(!sInstance, "Shouldn't initialize more than once");
 
   // See StaticPrefs for the default values of these preferences.
 
   // Length of time before an unused surface is removed from the cache, in
   // milliseconds.
   uint32_t surfaceCacheExpirationTimeMS =
-      StaticPrefs::image_mem_surfacecache_min_expiration_ms();
+      StaticPrefs::image_mem_surfacecache_min_expiration_ms_AtStartup();
 
   // What fraction of the memory used by the surface cache we should discard
   // when we get a memory pressure notification. This value is interpreted as
   // 1/N, so 1 means to discard everything, 2 means to discard about half of the
   // memory we're using, and so forth. We clamp it to avoid division by zero.
   uint32_t surfaceCacheDiscardFactor =
-      max(StaticPrefs::image_mem_surfacecache_discard_factor(), 1u);
+      max(StaticPrefs::image_mem_surfacecache_discard_factor_AtStartup(), 1u);
 
   // Maximum size of the surface cache, in kilobytes.
   uint64_t surfaceCacheMaxSizeKB =
-      StaticPrefs::image_mem_surfacecache_max_size_kb();
+      StaticPrefs::image_mem_surfacecache_max_size_kb_AtStartup();
 
   // A knob determining the actual size of the surface cache. Currently the
   // cache is (size of main memory) / (surface cache size factor) KB
   // or (surface cache max size) KB, whichever is smaller. The formula
   // may change in the future, though.
   // For example, a value of 4 would yield a 256MB cache on a 1GB machine.
   // The smallest machines we are likely to run this code on have 256MB
   // of memory, which would yield a 64MB cache on this setting.
   // We clamp this value to avoid division by zero.
   uint32_t surfaceCacheSizeFactor =
-      max(StaticPrefs::image_mem_surfacecache_size_factor(), 1u);
+      max(StaticPrefs::image_mem_surfacecache_size_factor_AtStartup(), 1u);
 
   // Compute the size of the surface cache.
   uint64_t memorySize = PR_GetPhysicalMemorySize();
   if (memorySize == 0) {
     MOZ_ASSERT_UNREACHABLE("PR_GetPhysicalMemorySize not implemented here");
     memorySize = 256 * 1024 * 1024;  // Fall back to 256MB.
   }
   uint64_t proposedSize = memorySize / surfaceCacheSizeFactor;
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -1246,18 +1246,18 @@ imgCacheQueue& imgLoader::GetCacheQueue(
   return aForChrome ? mChromeCacheQueue : mCacheQueue;
 }
 
 imgCacheQueue& imgLoader::GetCacheQueue(const ImageCacheKey& aKey) {
   return GetCacheQueue(aKey.IsChrome());
 }
 
 void imgLoader::GlobalInit() {
-  sCacheTimeWeight = StaticPrefs::image_cache_timeweight() / 1000.0;
-  int32_t cachesize = StaticPrefs::image_cache_size();
+  sCacheTimeWeight = StaticPrefs::image_cache_timeweight_AtStartup() / 1000.0;
+  int32_t cachesize = StaticPrefs::image_cache_size_AtStartup();
   sCacheMaxSize = cachesize > 0 ? cachesize : 0;
 
   sMemReporter = new imgMemoryReporter();
   RegisterStrongAsyncMemoryReporter(sMemReporter);
   RegisterImagesContentUsedUncompressedDistinguishedAmount(
       imgMemoryReporter::ImagesContentUsedUncompressedDistinguishedAmount);
 }
 
--- a/image/test/gtest/TestSurfaceCache.cpp
+++ b/image/test/gtest/TestSurfaceCache.cpp
@@ -38,18 +38,19 @@ TEST_F(ImageSurfaceCache, Factor2) {
 
   // Figure out how much data we have.
   uint64_t length;
   nsresult rv = inputStream->Available(&length);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
   // Ensures we meet the threshold for FLAG_SYNC_DECODE_IF_FAST to do sync
   // decoding without the implications of FLAG_SYNC_DECODE.
-  ASSERT_LT(length, static_cast<uint64_t>(
-                        StaticPrefs::image_mem_decode_bytes_at_a_time()));
+  ASSERT_LT(length,
+            static_cast<uint64_t>(
+                StaticPrefs::image_mem_decode_bytes_at_a_time_AtStartup()));
 
   // Write the data into the image.
   rv = image->OnImageDataAvailable(nullptr, nullptr, inputStream, 0,
                                    static_cast<uint32_t>(length));
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
   // Let the image know we've sent all the data.
   rv = image->OnImageDataComplete(nullptr, nullptr, NS_OK, true);
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -6012,17 +6012,17 @@ void PresShell::Paint(nsView* aViewToPai
   NS_ASSERTION(aViewToPaint, "null view");
 
   MOZ_ASSERT(!mApproximateFrameVisibilityVisited, "Should have been cleared");
 
   if (!mIsActive) {
     return;
   }
 
-  if (StaticPrefs::apz_keyboard_enabled()) {
+  if (StaticPrefs::apz_keyboard_enabled_AtStartup()) {
     // Update the focus target for async keyboard scrolling. This will be
     // forwarded to APZ by nsDisplayList::PaintRoot. We need to to do this
     // before we enter the paint phase because dispatching eVoid events can
     // cause layout to happen.
     mAPZFocusTarget = FocusTarget(this, mAPZFocusSequenceNumber);
   }
 
   nsPresContext* presContext = GetPresContext();
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -771,17 +771,17 @@ bool nsLayoutUtils::AllowZoomingForDocum
 float nsLayoutUtils::GetCurrentAPZResolutionScale(PresShell* aPresShell) {
   return aPresShell ? aPresShell->GetCumulativeNonRootScaleResolution() : 1.0;
 }
 
 // Return the maximum displayport size, based on the LayerManager's maximum
 // supported texture size. The result is in app units.
 static nscoord GetMaxDisplayPortSize(nsIContent* aContent,
                                      nsPresContext* aFallbackPrescontext) {
-  MOZ_ASSERT(!StaticPrefs::layers_enable_tiles(),
+  MOZ_ASSERT(!StaticPrefs::layers_enable_tiles_AtStartup(),
              "Do not clamp displayports if tiling is enabled");
 
   // Pick a safe maximum displayport size for sanity purposes. This is the
   // lowest maximum texture size on tileless-platforms (Windows, D3D10).
   // If the gfx.max-texture-size pref is set, further restrict the displayport
   // size to fit within that, because the compositor won't upload stuff larger
   // than this size.
   nscoord safeMaximum = aFallbackPrescontext
@@ -908,17 +908,17 @@ static nsRect GetDisplayPortFromMarginsD
   //   the choosing of the resolution to display-list building time.
   ScreenSize alignment;
 
   PresShell* presShell = presContext->PresShell();
   MOZ_ASSERT(presShell);
 
   if (presShell->IsDisplayportSuppressed()) {
     alignment = ScreenSize(1, 1);
-  } else if (StaticPrefs::layers_enable_tiles()) {
+  } else if (StaticPrefs::layers_enable_tiles_AtStartup()) {
     // Don't align to tiles if they are too large, because we could expand
     // the displayport by a lot which can take more paint time. It's a tradeoff
     // though because if we don't align to tiles we have more waste on upload.
     IntSize tileSize = gfxVars::TileSize();
     alignment = ScreenSize(std::min(256, tileSize.width),
                            std::min(256, tileSize.height));
   } else {
     // If we're not drawing with tiles then we need to be careful about not
@@ -930,17 +930,17 @@ static nsRect GetDisplayPortFromMarginsD
   // Avoid division by zero.
   if (alignment.width == 0) {
     alignment.width = 128;
   }
   if (alignment.height == 0) {
     alignment.height = 128;
   }
 
-  if (StaticPrefs::layers_enable_tiles()) {
+  if (StaticPrefs::layers_enable_tiles_AtStartup()) {
     // Expand the rect by the margins
     screenRect.Inflate(aMarginsData->mMargins);
   } else {
     // Calculate the displayport to make sure we fit within the max texture size
     // when not tiling.
     nscoord maxSizeAppUnits = GetMaxDisplayPortSize(aContent, presContext);
     MOZ_ASSERT(maxSizeAppUnits < nscoord_MAX);
 
@@ -1142,17 +1142,17 @@ static bool GetDisplayPortImpl(
   } else if (isDisplayportSuppressed ||
              nsLayoutUtils::ShouldDisableApzForElement(aContent)) {
     DisplayPortMarginsPropertyData noMargins(ScreenMargin(), 1);
     result = GetDisplayPortFromMarginsData(aContent, &noMargins, aMultiplier);
   } else {
     result = GetDisplayPortFromMarginsData(aContent, marginsData, aMultiplier);
   }
 
-  if (!StaticPrefs::layers_enable_tiles()) {
+  if (!StaticPrefs::layers_enable_tiles_AtStartup()) {
     // Perform the desired error handling if the displayport dimensions
     // exceeds the maximum allowed size
     nscoord maxSize = GetMaxDisplayPortSize(aContent, nullptr);
     if (result.width > maxSize || result.height > maxSize) {
       switch (aBehaviour) {
         case MaxSizeExceededBehaviour::Assert:
           NS_ASSERTION(false, "Displayport must be a valid texture size");
           break;
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2096,17 +2096,17 @@ ScrollFrameHelper::ScrollFrameHelper(nsC
       mMinimumScaleSizeChanged(false),
       mVelocityQueue(aOuter->PresContext()) {
   if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
     mScrollbarActivity = new ScrollbarActivity(do_QueryFrame(aOuter));
   }
 
   EnsureFrameVisPrefsCached();
 
-  if (IsAlwaysActive() && StaticPrefs::layers_enable_tiles() &&
+  if (IsAlwaysActive() && StaticPrefs::layers_enable_tiles_AtStartup() &&
       !nsLayoutUtils::UsesAsyncScrolling(mOuter) && mOuter->GetContent()) {
     // If we have tiling but no APZ, then set a 0-margin display port on
     // active scroll containers so that we paint by whole tile increments
     // when scrolling.
     nsLayoutUtils::SetDisplayPortMargins(
         mOuter->GetContent(), mOuter->PresShell(), ScreenMargin(), 0);
     nsLayoutUtils::SetZeroMarginDisplayPortOnAsyncScrollableAncestors(mOuter);
   }
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -6200,17 +6200,17 @@ static bool ChooseScaleAndSetTransform(
       aContainerFrame, aContainerItem, aVisibleRect, aIncomingScale.mXScale,
       aIncomingScale.mYScale, transform2d, canDraw2D);
 
   // If this is a transform container layer, then pre-rendering might
   // mean we try render a layer bigger than the max texture size. If we have
   // tiling, that's not a problem, since we'll automatically choose a tiled
   // layer for layers of that size. If not, we need to apply clamping to
   // prevent this.
-  if (aTransform && !StaticPrefs::layers_enable_tiles()) {
+  if (aTransform && !StaticPrefs::layers_enable_tiles_AtStartup()) {
     RestrictScaleToMaxLayerSize(scale, aVisibleRect, aContainerFrame, aLayer);
   }
 
   // Store the inverse of our resolution-scale on the layer
   aLayer->SetBaseTransform(transform);
   aLayer->SetPreScale(1.0f / scale.width, 1.0f / scale.height);
   aLayer->SetInheritedScale(aIncomingScale.mXScale, aIncomingScale.mYScale);
 
@@ -7150,17 +7150,17 @@ void FrameLayerBuilder::PaintItems(std::
 
 /**
  * Returns true if it is preferred to draw the list of display
  * items separately for each rect in the visible region rather
  * than clipping to a complex region.
  */
 static bool ShouldDrawRectsSeparately(DrawTarget* aDrawTarget,
                                       DrawRegionClip aClip) {
-  if (!StaticPrefs::layout_paint_rects_separately() ||
+  if (!StaticPrefs::layout_paint_rects_separately_AtStartup() ||
       aClip == DrawRegionClip::NONE) {
     return false;
   }
 
   return !aDrawTarget->SupportsRegionClipping();
 }
 
 static void DrawForcedBackgroundColor(DrawTarget& aDrawTarget,
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6965,17 +6965,17 @@ void nsDisplayOwnLayer::WriteDebugInfo(s
 
 nsDisplayRenderRoot::nsDisplayRenderRoot(
     nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList,
     const ActiveScrolledRoot* aActiveScrolledRoot, wr::RenderRoot aRenderRoot)
     : nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true),
       mRenderRoot(aRenderRoot),
       mBuiltWRCommands(false) {
   MOZ_ASSERT(aRenderRoot != wr::RenderRoot::Default);
-  MOZ_ASSERT(StaticPrefs::gfx_webrender_split_render_roots());
+  MOZ_ASSERT(StaticPrefs::gfx_webrender_split_render_roots_AtStartup());
   ExpandDisplayListBuilderRenderRootRect(aBuilder);
   MOZ_COUNT_CTOR(nsDisplayRenderRoot);
 }
 
 void nsDisplayRenderRoot::Destroy(nsDisplayListBuilder* aBuilder) {
   if (mBuiltWRCommands && aBuilder) {
     aBuilder->SetNeedsDisplayListBuild(mRenderRoot);
   }
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -4491,33 +4491,33 @@ Result<Ok, const char*> Preferences::Ini
   StaticPrefs::InitAll(aIsStartup);
 
   if (!XRE_IsParentProcess()) {
     MOZ_DIAGNOSTIC_ASSERT(gSharedMap);
 
 #ifdef DEBUG
     // For a VarCache pref like this:
     //
-    //   VARCACHE_PREF($POLICY, "my.pref", my_pref, int32_t, 99)
+    //   VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
     //
     // we generate checking code like this:
     //
     //   MOZ_ASSERT(PreferencesInternalMethods::GetPref<int32_t>(name, value) ==
     //              StaticPrefs::my_pref(),
     //              "Incorrect cached value for my.pref");
     //
     // This checks that all VarCache preferences match their current values.
     // This can currently fail if the default value of a static VarCache
     // preference is changed in a preference file or at runtime, rather than in
     // StaticPrefList*.h.
     //
 #  define PREF(name, cpp_type, value)
-#  define VARCACHE_PREF(policy, name, id, cpp_type, value)                 \
+#  define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value)   \
     MOZ_ASSERT(PreferencesInternalMethods::GetPref<StripAtomic<cpp_type>>( \
-                   name, value) == StaticPrefs::id(),                      \
+                   name, value) == StaticPrefs::full_id(),                 \
                "Incorrect cached value for " name);
 #  include "mozilla/StaticPrefListAll.h"
 #  undef PREF
 #  undef VARCACHE_PREF
 #endif
 
     return Ok();
   }
@@ -5422,36 +5422,36 @@ void MaybeInitOncePrefs() {
     SyncRunnable::DispatchToThread(
         SystemGroup::EventTargetFor(TaskCategory::Other), runnable);
   }
   sOncePrefRead = true;
 }
 
 // For a pref like this:
 //
-//   VARCACHE_PREF($POLICY, "my.pref", my_pref, int32_t, 99)
+//   VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
 //
 // we generate a variable definition like this:
 //
 //   int32_t sVarCache_my_pref(99);
 //
 #define PREF(name, cpp_type, value)
-#define VARCACHE_PREF(policy, name, id, cpp_type, default_value) \
-  cpp_type sVarCache_##id(default_value);
+#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, default_value) \
+  cpp_type sVarCache_##full_id(default_value);
 #include "mozilla/StaticPrefListAll.h"
 #undef PREF
 #undef VARCACHE_PREF
 
 static void InitAll(bool aIsStartup) {
   bool isParent = XRE_IsParentProcess();
 
   // For prefs like these:
   //
   //   PREF("foo.bar.baz", bool, true)
-  //   VARCACHE_PREF($POLICY, "my.pref", my_pref, int32_t, 99)
+  //   VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
   //
   // we generate registration calls like this:
   //
   //   if (isParent) {
   //     SetPref_bool("foo.bar.baz", true);
   //   }
   //   InitVarCachePref(UpdatePolicy::Live, "my.pref", &sVarCache_my_pref,
   //                    99, aIsStartup, isParent);
@@ -5462,28 +5462,28 @@ static void InitAll(bool aIsStartup) {
   // which prevents automatic int-to-float coercion.
   //
   // In content processes, we rely on the parent to send us the correct initial
   // values via shared memory, so we do not re-initialize them here.
 #define PREF(name, cpp_type, value)  \
   if (isParent) {                    \
     SetPref_##cpp_type(name, value); \
   }
-#define VARCACHE_PREF(policy, name, id, cpp_type, value)           \
-  InitVarCachePref(UpdatePolicy::policy, NS_LITERAL_CSTRING(name), \
-                   &sVarCache_##id, value, aIsStartup, isParent);
+#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value) \
+  InitVarCachePref(UpdatePolicy::policy, NS_LITERAL_CSTRING(name),     \
+                   &sVarCache_##full_id, value, aIsStartup, isParent);
 #include "mozilla/StaticPrefListAll.h"
 #undef PREF
 #undef VARCACHE_PREF
 }
 
 static void InitOncePrefs() {
   // For a pref like this:
   //
-  //   VARCACHE_PREF($POLICY, "my.pref", my_pref, int32_t, 99)
+  //   VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
   //
   // we generate an initialization (in a non-DEBUG build) like this:
   //
   //   if (UpdatePolicy::$POLICY == UpdatePolicy::Once) {
   //     sVarCache_my_pref = PreferencesInternalMethods::GetPref("my.pref", 99);
   //   }
   //
   // This is done to get the potentially updated Preference value as we didn't
@@ -5491,41 +5491,42 @@ static void InitOncePrefs() {
   //
   // On debug build, we also install a mechanism that allows to check if the
   // original Preference is being modified once `Once` StaticPrefs have been
   // initialized as this would indicate a likely misuse of `Once` StaticPrefs
   // and that maybe instead they should have been made `Live`.
   //
 #define PREF(name, cpp_type, value)
 #ifdef DEBUG
-#  define VARCACHE_PREF(policy, name, id, cpp_type, value)                     \
+#  define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value)       \
     if (UpdatePolicy::policy == UpdatePolicy::Once) {                          \
       MOZ_ASSERT(gOnceStaticPrefsAntiFootgun);                                 \
-      sVarCache_##id = PreferencesInternalMethods::GetPref(                    \
+      sVarCache_##full_id = PreferencesInternalMethods::GetPref(               \
           name, StripAtomic<cpp_type>(value));                                 \
       auto checkPref = [&]() {                                                 \
         MOZ_ASSERT(sOncePrefRead);                                             \
-        StripAtomic<cpp_type> staticPrefValue = id();                          \
+        StripAtomic<cpp_type> staticPrefValue = full_id();                     \
         StripAtomic<cpp_type> preferenceValue =                                \
-            PreferencesInternalMethods::GetPref(GetPrefName_##id(),            \
+            PreferencesInternalMethods::GetPref(GetPrefName_##base_id(),       \
                                                 StripAtomic<cpp_type>(value)); \
-        MOZ_ASSERT(                                                            \
-            staticPrefValue == preferenceValue,                                \
-            "Preference '" name "' got modified since StaticPrefs::" #id       \
-            " got initialized. Consider using a `Live` StaticPrefs instead");  \
+        MOZ_ASSERT(staticPrefValue == preferenceValue,                         \
+                   "Preference '" name                                         \
+                   "' got modified since StaticPrefs::" #full_id               \
+                   " was initialized. Consider using an `always` mirror kind " \
+                   "instead");                                                 \
       };                                                                       \
       gOnceStaticPrefsAntiFootgun->insert(                                     \
-          std::pair<const char*, AntiFootgunCallback>(GetPrefName_##id(),      \
+          std::pair<const char*, AntiFootgunCallback>(GetPrefName_##base_id(), \
                                                       std::move(checkPref)));  \
     }
 #else
-#  define VARCACHE_PREF(policy, name, id, cpp_type, value)  \
-    if (UpdatePolicy::policy == UpdatePolicy::Once) {       \
-      sVarCache_##id = PreferencesInternalMethods::GetPref( \
-          name, StripAtomic<cpp_type>(value));              \
+#  define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value) \
+    if (UpdatePolicy::policy == UpdatePolicy::Once) {                    \
+      sVarCache_##full_id = PreferencesInternalMethods::GetPref(         \
+          name, StripAtomic<cpp_type>(value));                           \
     }
 #endif
 
 #include "mozilla/StaticPrefListAll.h"
 #undef PREF
 #undef VARCACHE_PREF
 }
 
@@ -5587,50 +5588,50 @@ namespace StaticPrefs {
 static void RegisterOncePrefs(SharedPrefMapBuilder& aBuilder) {
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_DIAGNOSTIC_ASSERT(!gSharedMap,
                         "Must be called before gSharedMap has been created");
   MaybeInitOncePrefs();
 
   // For a pref like this:
   //
-  //   VARCACHE_PREF($POLICY, "my.pref", my_pref, int32_t, 99)
+  //   VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
   //
   // we generate a save call like this:
   //
   //   if (UpdatePolicy::$POLICY == UpdatePolicy::Once) {
   //     SaveOncePrefToSharedMap(aBuilder, ONCE_PREF_NAME(my.pref),
   //                             sVarCache_my_pref);
   //   }
   //
   // `Once` StaticPrefs values will be stored in a hidden and locked preferences
   // in the global SharedPreferenceMap. In order for those preferences to be
   // hidden and not appear in about:config nor ever be stored to disk, we add
   // the "$$$" prefix and suffix to the preference name and set the IsVisible
   // flag to false.
   //
 #define PREF(name, cpp_type, value)
-#define VARCACHE_PREF(policy, name, id, cpp_type, value)            \
-  if (UpdatePolicy::policy == UpdatePolicy::Once) {                 \
-    SaveOncePrefToSharedMap(aBuilder, ONCE_PREF_NAME(name),         \
-                            StripAtomic<cpp_type>(sVarCache_##id)); \
+#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value)   \
+  if (UpdatePolicy::policy == UpdatePolicy::Once) {                      \
+    SaveOncePrefToSharedMap(aBuilder, ONCE_PREF_NAME(name),              \
+                            StripAtomic<cpp_type>(sVarCache_##full_id)); \
   }
 #include "mozilla/StaticPrefListAll.h"
 #undef PREF
 #undef VARCACHE_PREF
 }
 
 static void InitStaticPrefsFromShared() {
   MOZ_ASSERT(!XRE_IsParentProcess());
   MOZ_DIAGNOSTIC_ASSERT(gSharedMap,
                         "Must be called once gSharedMap has been created");
 
   // For a prefs like this:
   //
-  //   VARCACHE_PREF($POLICY, "my.pref", my_pref, int32_t, 99)
+  //   VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
   //
   // we generate an initialization like this:
   //
   //   {
   //     int32_t val;
   //     nsresult rv;
   //     if (UpdatePolicy::$POLICY == UpdatePolicy::Once) {
   //       rv = PreferencesInternalMethods::GetSharedPrefValue(
@@ -5638,28 +5639,28 @@ static void InitStaticPrefsFromShared() 
   //     } else if (UpdatePolicy::Once == UpdatePolicy::Live) {
   //       rv = PreferencesInternalMethods::GetSharedPrefValue("my.pref", &val);
   //     }
   //     MOZ_DIAGNOSTIC_ALWAYS_TRUE(NS_SUCCEEDED(rv));
   //     sVarCache_my_pref = val;
   //   }
   //
 #define PREF(name, cpp_type, value)
-#define VARCACHE_PREF(policy, name, id, cpp_type, value)               \
+#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, value) \
   {                                                                    \
     StripAtomic<cpp_type> val;                                         \
     nsresult rv;                                                       \
     if (UpdatePolicy::policy == UpdatePolicy::Once) {                  \
       rv = PreferencesInternalMethods::GetSharedPrefValue(             \
           ONCE_PREF_NAME(name), &val);                                 \
     } else {                                                           \
       rv = PreferencesInternalMethods::GetSharedPrefValue(name, &val); \
     }                                                                  \
     MOZ_DIAGNOSTIC_ALWAYS_TRUE(NS_SUCCEEDED(rv));                      \
-    StaticPrefs::sVarCache_##id = val;                                 \
+    StaticPrefs::sVarCache_##full_id = val;                            \
   }
 #include "mozilla/StaticPrefListAll.h"
 #undef PREF
 #undef VARCACHE_PREF
 
   // `Once` StaticPrefs have been set to their value in the step above and
   // outside the parent process they are immutable. So we set sOncePrefRead
   // so that we can directly skip any lazy initializations.
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -47,55 +47,62 @@
 # - `value` is the default value. Its type should be appropriate for
 #   <cpp-type>, otherwise the generated code will fail to compile. A complex
 #   C++ numeric expressions like `60 * 60` (which the YAML parser cannot treat
 #   as an integer or float) is treated as a string and passed through without
 #   change, which is useful.
 #
 # - `mirror` indicates how the pref value is mirrored into a C++ variable.
 #
-#   * `never`: There is no global variable mirror. The pref value can only be
+#   * `never`: There is no C++ mirror variable. The pref value can only be
 #     accessed via the standard libpref API functions.
 #
 #   * `once`: The pref value is mirrored into a variable at startup; the
 #     mirror variable is left unchanged after that. (The exact point at which
 #     all `once` mirror variables are set is when the first `once` mirror
-#     variable is accessed, via its getter function.) This is mostly useful
-#     for graphics prefs where we often don't want a new pref value to apply
-#     until restart. Otherwise, this update policy is best avoided because its
+#     variable is accessed, via its getter function.) This is mostly useful for
+#     graphics prefs where we often don't want a new pref value to apply until
+#     restart. Otherwise, this update policy is best avoided because its
 #     behaviour can cause confusion and bugs.
 #
-#   * `always`: The mirror value is always kept in sync with the pref value.
+#   * `always`: The mirror variable is always kept in sync with the pref value.
 #     This is the most common choice.
 #
-#   The getter function's name is the same as the pref's name, but with '.' or
-#   '-' chars converted to '_', to make a valid identifier. For example, the
-#   getter for `foo.bar_baz` is `foo_bar_baz()`. This is ugly but clear, and
-#   you can search for both the pref name and the getter using the regexp
-#   /foo.bar.baz/.
-#
-#   Using the getter function to read the pref's value has the two following
-#   advantages over the normal API functions.
+#   When a mirror variable is present, a getter will be created that can access
+#   it. Using the getter function to read the pref's value has the two
+#   following advantages over the normal API functions.
 #
 #   * A direct variable access is faster than a hash table lookup.
 #
-#   * A variable can be accessed off the main thread. If a pref *is* accessed
-#     off the main thread, it should have an atomic type. Assertions enforce
-#     this.
+#   * A mirror variable can be accessed off the main thread. If a pref *is*
+#     accessed off the main thread, it should have an atomic type. Assertions
+#     enforce this.
 #
-#   Note that Rust code must access the global variable directly, rather than
-#   via the getter.
+#   Note that Rust code must access the mirror variable directly, rather than
+#   via the getter function.
 #
 # - `do_not_use_directly` dictates if `_DoNotUseDirectly` should be appended to
 #   the name of the getter function. This is simply a naming convention
 #   indicating that there is some other wrapper getter function that should be
 #   used in preference to the normal static pref getter. Defaults to `false` if
 #   not present. Cannot be used with a `never` mirror value, because there is
 #   no getter function in that case.
 #
+# The getter function's base name is the same as the pref's name, but with
+# '.' or '-' chars converted to '_', to make a valid identifier. For example,
+# the getter for `foo.bar_baz` is `foo_bar_baz()`. This is ugly but clear,
+# and you can search for both the pref name and the getter using the regexp
+# /foo.bar.baz/. Suffixes are added as follows:
+#
+# - If the `mirror` value is `once`, `_AtStartup` is appended, to indicate the
+#   value was obtained at startup.
+#
+# - If the `do_not_use_directly` value is true, `_DoNotUseDirectly` is
+#   appended.
+#
 # Preprocessor
 # ------------
 # Note finally that this file is preprocessed by preprocessor.py, not the C++
 # preprocessor. As a result, the following things may be surprising.
 #
 # - YAML comments start with a '#', so putting a comment on the same line as a
 #   preprocessor directive is dubious. E.g. avoid lines like `#define X 3 #
 #   three` because the ` # three` will be part of `X`.
--- a/modules/libpref/init/StaticPrefListBegin.h
+++ b/modules/libpref/init/StaticPrefListBegin.h
@@ -11,17 +11,17 @@
 #include "StaticPrefsBase.h"
 #include "MainThreadUtils.h"  // for NS_IsMainThread()
 
 namespace mozilla {
 namespace StaticPrefs {
 
 // For a VarCache pref like this:
 //
-//   VARCACHE_PREF($POLICY, "my.pref", my_pref, int32_t, 99)
+//   VARCACHE_PREF($POLICY, "my.pref", my_pref, my_pref, int32_t, 99)
 //
 // we generate an extern variable declaration and three getter
 // declarations/definitions.
 //
 //     extern int32_t sVarCache_my_pref;
 //     inline int32_t my_pref() {
 //       if (UpdatePolicy::$POLICY != UpdatePolicy::Once) {
 //         return sVarCache_my_pref;
@@ -31,23 +31,25 @@ namespace StaticPrefs {
 //     }
 //     inline const char* GetPrefName_my_pref() { return "my.pref"; }
 //     inline int32_t GetPrefDefault_my_pref() { return 99; }
 //
 // The extern declaration of the variable is necessary for bindgen to see it
 // and generate Rust bindings.
 //
 #define PREF(name, cpp_type, default_value)
-#define VARCACHE_PREF(policy, name, id, cpp_type, default_value) \
-  extern cpp_type sVarCache_##id;                                \
-  inline StripAtomic<cpp_type> id() {                            \
-    if (UpdatePolicy::policy != UpdatePolicy::Once) {            \
-      MOZ_DIAGNOSTIC_ASSERT(                                     \
-          IsAtomic<cpp_type>::value || NS_IsMainThread(),        \
-          "Non-atomic static pref '" name                        \
-          "' being accessed on background thread by getter");    \
-      return sVarCache_##id;                                     \
-    }                                                            \
-    MaybeInitOncePrefs();                                        \
-    return sVarCache_##id;                                       \
-  }                                                              \
-  inline const char* GetPrefName_##id() { return name; }         \
-  inline StripAtomic<cpp_type> GetPrefDefault_##id() { return default_value; }
+#define VARCACHE_PREF(policy, name, base_id, full_id, cpp_type, default_value) \
+  extern cpp_type sVarCache_##full_id;                                         \
+  inline StripAtomic<cpp_type> full_id() {                                     \
+    if (UpdatePolicy::policy != UpdatePolicy::Once) {                          \
+      MOZ_DIAGNOSTIC_ASSERT(                                                   \
+          IsAtomic<cpp_type>::value || NS_IsMainThread(),                      \
+          "Non-atomic static pref '" name                                      \
+          "' being accessed on background thread by getter");                  \
+      return sVarCache_##full_id;                                              \
+    }                                                                          \
+    MaybeInitOncePrefs();                                                      \
+    return sVarCache_##full_id;                                                \
+  }                                                                            \
+  inline const char* GetPrefName_##base_id() { return name; }                  \
+  inline StripAtomic<cpp_type> GetPrefDefault_##base_id() {                    \
+    return default_value;                                                      \
+  }
--- a/modules/libpref/init/StaticPrefList_accessibility.h
+++ b/modules/libpref/init/StaticPrefList_accessibility.h
@@ -10,19 +10,21 @@
 // See StaticPrefList.h for details on how these entries are defined.
 
 // clang-format off
 
 VARCACHE_PREF(
   Live,
   "accessibility.monoaudio.enable",
    accessibility_monoaudio_enable,
+   accessibility_monoaudio_enable,
   RelaxedAtomicBool, false
 )
 
 VARCACHE_PREF(
   Live,
   "accessibility.browsewithcaret",
    accessibility_browsewithcaret,
+   accessibility_browsewithcaret,
   RelaxedAtomicBool, false
 )
 
 // clang-format on
--- a/modules/libpref/init/generate_static_pref_list.py
+++ b/modules/libpref/init/generate_static_pref_list.py
@@ -54,47 +54,52 @@ mirror_templates = {
     'never': '''\
 PREF("{name}", {typ}, {value})
 ''',
 
     'once': '''\
 VARCACHE_PREF(
   Once,
   "{name}",
-   {id},
+   {base_id},
+   {full_id},
   {typ}, {value}
 )
 ''',
 
     'always': '''\
 VARCACHE_PREF(
   Live,
   "{name}",
-   {id},
+   {base_id},
+   {full_id},
   {typ}, {value}
 )
 ''',
 }
 
 
 def error(msg):
     raise ValueError(msg)
 
 
-def pref_id(pref):
+def pref_ids(pref):
     if pref['mirror'] == 'never':
         if pref.get('do_not_use_directly'):
             error('`do_not_use_directly` uselessly set with `mirror` value '
                   '`never` for pref `{}`'.format(pref['name']))
-        return None
+        return (None, None)
 
-    id = pref['name'].replace('.', '_').replace('-', '_')
+    base_id = pref['name'].replace('.', '_').replace('-', '_')
+    full_id = base_id
+    if pref['mirror'] == 'once':
+        full_id += '_AtStartup'
     if pref.get('do_not_use_directly'):
-        id += '_DoNotUseDirectly'
-    return id
+        full_id += '_DoNotUseDirectly'
+    return (base_id, full_id)
 
 
 def generate_header(pref_list):
     lines = [header_template]
 
     prev_pref = None
     for pref in pref_list:
         # Check all given keys are known ones.
@@ -147,19 +152,21 @@ def generate_header(pref_list):
         if 'mirror' not in pref:
             error('missing `mirror` key for pref `{}`'.format(name))
         mirror = pref['mirror']
         if mirror not in mirror_templates:
             error('invalid `mirror` value `{}` for pref `{}`'
                   .format(mirror, name))
 
         # Generate the C++ code.
+        ids = pref_ids(pref)
         lines.append(mirror_templates[mirror].format(
             name=name,
-            id=pref_id(pref),
+            base_id=ids[0],
+            full_id=ids[1],
             typ=typ,
             value=value,
         ))
 
         prev_pref = pref
 
     return '\n'.join(lines)
 
--- a/modules/libpref/test/test_generate_static_pref_list.py
+++ b/modules/libpref/test/test_generate_static_pref_list.py
@@ -88,55 +88,61 @@ good_output = '''\
 // This file was autogenerated by generate_static_pref_list.py. DO NOT EDIT.
 
 PREF("my.bool", bool, false)
 
 VARCACHE_PREF(
   Once,
   "my.int",
    my_int,
+   my_int_AtStartup,
   int32_t, -123
 )
 
 VARCACHE_PREF(
   Live,
   "my.uint",
    my_uint,
+   my_uint,
   uint32_t, 999
 )
 
 VARCACHE_PREF(
   Once,
   "my.float",
-   my_float_DoNotUseDirectly,
+   my_float,
+   my_float_AtStartup_DoNotUseDirectly,
   float, 0.0f
 )
 
 PREF("my.string", String, "foo\\"bar")
 
 PREF("my.string2", String, "foobar")
 
 VARCACHE_PREF(
   Live,
   "my.atomic.bool",
    my_atomic_bool,
+   my_atomic_bool,
   RelaxedAtomicBool, true
 )
 
 VARCACHE_PREF(
   Live,
   "my.atomic.int",
+   my_atomic_int,
    my_atomic_int_DoNotUseDirectly,
   ReleaseAcquireAtomicInt32, 10 + 10 * 20
 )
 
 VARCACHE_PREF(
   Once,
   "my.atomic.uint",
    my_atomic_uint,
+   my_atomic_uint_AtStartup,
   SequentiallyConsistentAtomicUint32, 68
 )
 
 PREF("my.atomic.float", AtomicFloat, 0.4455667)
 '''
 
 # A lot of bad inputs, each with an accompanying error message. Listed in order
 # of the relevant `error` calls within generate_static_pref_list.py.
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -600,17 +600,17 @@ nsresult GfxInfoBase::Init() {
 
 NS_IMETHODIMP
 GfxInfoBase::GetFeatureStatus(int32_t aFeature, nsACString& aFailureId,
                               int32_t* aStatus) {
   // Ignore the gfx.blocklist.all pref on release and beta.
 #if defined(RELEASE_OR_BETA)
   int32_t blocklistAll = 0;
 #else
-  int32_t blocklistAll = StaticPrefs::gfx_blocklist_all();
+  int32_t blocklistAll = StaticPrefs::gfx_blocklist_all_AtStartup();
 #endif
   if (blocklistAll > 0) {
     gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false))
         << "Forcing blocklisting all features";
     *aStatus = FEATURE_BLOCKED_DEVICE;
     aFailureId = "FEATURE_FAILURE_BLOCK_ALL";
     return NS_OK;
   } else if (blocklistAll < 0) {
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -2734,17 +2734,17 @@ static NSMutableSet* gSwizzledFrameViewC
                                 @selector(FrameView__closeButtonOrigin));
     }
     IMP _fullScreenButtonOrigin =
         class_getMethodImplementation(frameViewClass, @selector(_fullScreenButtonOrigin));
     if (_fullScreenButtonOrigin && _fullScreenButtonOrigin != our_fullScreenButtonOrigin) {
       nsToolkit::SwizzleMethods(frameViewClass, @selector(_fullScreenButtonOrigin),
                                 @selector(FrameView__fullScreenButtonOrigin));
     }
-    if (!StaticPrefs::gfx_core_animation_enabled()) {
+    if (!StaticPrefs::gfx_core_animation_enabled_AtStartup()) {
       // When we're not using CoreAnimation, we need to override the
       // _wantsFloatingTitlebar method to return NO, because the "floating
       // titlebar" overlaps in a glitchy way with the NSOpenGLContext when we're
       // drawing in the titlebar. These glitches do not appear when we use a
       // CoreAnimation layer instead of an NSView-attached NSOpenGLContext.
       IMP _wantsFloatingTitlebar =
           class_getMethodImplementation(frameViewClass, @selector(_wantsFloatingTitlebar));
       if (_wantsFloatingTitlebar && _wantsFloatingTitlebar != our_wantsFloatingTitlebar) {
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -888,17 +888,17 @@ void nsBaseWidget::ConfigureAPZCTreeMana
   ConfigureAPZControllerThread();
 
   float dpi = GetDPI();
   // On Android the main thread is not the controller thread
   APZThreadUtils::RunOnControllerThread(
       NewRunnableMethod<float>("layers::IAPZCTreeManager::SetDPI", mAPZC,
                                &IAPZCTreeManager::SetDPI, dpi));
 
-  if (StaticPrefs::apz_keyboard_enabled()) {
+  if (StaticPrefs::apz_keyboard_enabled_AtStartup()) {
     KeyboardMap map = nsXBLWindowKeyHandler::CollectKeyboardShortcuts();
     // On Android the main thread is not the controller thread
     APZThreadUtils::RunOnControllerThread(NewRunnableMethod<KeyboardMap>(
         "layers::IAPZCTreeManager::SetKeyboardMap", mAPZC,
         &IAPZCTreeManager::SetKeyboardMap, map));
   }
 
   RefPtr<IAPZCTreeManager> treeManager = mAPZC;  // for capture by the lambdas