gfx/thebes/gfxPrefs.cpp
author shindli <shindli@mozilla.com>
Sun, 03 Dec 2017 01:10:14 +0200
changeset 449028 7a19568290c61d7a510b54455419b086e66cc6db
parent 447409 7f9bb0d53730d0919e51004ca01529522ad039d4
child 482886 aedd8cf3e783b0d982ed92d01c6996327a71f1cb
permissions -rw-r--r--
Backed out 2 changesets (bug 1420954) for build failure in /builds/worker/workspace/build/src/obj-firefox/dist/include/nsIURIMutator.h:340:3: r=backout on a CLOSED TREE Backed out changeset 8ce0a0d49d9e (bug 1420954) Backed out changeset 480c6e1721e9 (bug 1420954)

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "gfxPrefs.h"

#include "MainThreadUtils.h"
#include "nsXULAppAPI.h"
#include "mozilla/Preferences.h"
#include "mozilla/Unused.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/GPUChild.h"
#include "mozilla/gfx/GPUProcessManager.h"

using namespace mozilla;

nsTArray<gfxPrefs::Pref*>* gfxPrefs::sGfxPrefList = nullptr;
gfxPrefs* gfxPrefs::sInstance = nullptr;
bool gfxPrefs::sInstanceHasBeenDestroyed = false;

gfxPrefs&
gfxPrefs::CreateAndInitializeSingleton() {
  MOZ_ASSERT(!sInstanceHasBeenDestroyed,
             "Should never recreate a gfxPrefs instance!");
  sGfxPrefList = new nsTArray<Pref*>();
  sInstance = new gfxPrefs;
  sInstance->Init();
  MOZ_ASSERT(SingletonExists());
  return *sInstance;
}

void
gfxPrefs::DestroySingleton()
{
  if (sInstance) {
    delete sInstance;
    sInstance = nullptr;
    sInstanceHasBeenDestroyed = true;
  }
  MOZ_ASSERT(!SingletonExists());
}

bool
gfxPrefs::SingletonExists()
{
  return sInstance != nullptr;
}

gfxPrefs::gfxPrefs()
{
  // UI, content, and plugin processes use XPCOM and should have prefs
  // ready by the time we initialize gfxPrefs.
  MOZ_ASSERT_IF(XRE_IsContentProcess() ||
                XRE_IsParentProcess() ||
                XRE_GetProcessType() == GeckoProcessType_Plugin,
                Preferences::IsServiceAvailable());

  gfxPrefs::AssertMainThread();
}

void
gfxPrefs::Init()
{
  // Set up Moz2D prefs.
  SetGfxLoggingLevelChangeCallback([](const GfxPrefValue& aValue) -> void {
    mozilla::gfx::LoggingPrefs::sGfxLogLevel = aValue.get_int32_t();
  });
}

gfxPrefs::~gfxPrefs()
{
  gfxPrefs::AssertMainThread();
  SetGfxLoggingLevelChangeCallback(nullptr);
  delete sGfxPrefList;
  sGfxPrefList = nullptr;
}

void gfxPrefs::AssertMainThread()
{
  MOZ_ASSERT(NS_IsMainThread(), "this code must be run on the main thread");
}

void
gfxPrefs::Pref::OnChange()
{
  if (auto gpm = gfx::GPUProcessManager::Get()) {
    if (gfx::GPUChild* gpu = gpm->GetGPUChild()) {
      GfxPrefValue value;
      GetLiveValue(&value);
      Unused << gpu->SendUpdatePref(gfx::GfxPrefSetting(mIndex, value));
    }
  }
  FireChangeCallback();
}

void
gfxPrefs::Pref::FireChangeCallback()
{
  if (mChangeCallback) {
    GfxPrefValue value;
    GetLiveValue(&value);
    mChangeCallback(value);
  }
}

void
gfxPrefs::Pref::SetChangeCallback(ChangeCallback aCallback)
{
  mChangeCallback = aCallback;

  if (!IsParentProcess() && IsPrefsServiceAvailable()) {
    // If we're in the parent process, we watch prefs by default so we can
    // send changes over to the GPU process. Otherwise, we need to add or
    // remove a watch for the pref now.
    if (aCallback) {
      WatchChanges(Name(), this);
    } else {
      UnwatchChanges(Name(), this);
    }
  }

  // Fire the callback once to make initialization easier for the caller.
  FireChangeCallback();
}

// On lightweight processes such as for GMP and GPU, XPCOM is not initialized,
// and therefore we don't have access to Preferences. When XPCOM is not
// available we rely on manual synchronization of gfxPrefs values over IPC.
/* static */ bool
gfxPrefs::IsPrefsServiceAvailable()
{
  return Preferences::IsServiceAvailable();
}

/* static */ bool
gfxPrefs::IsParentProcess()
{
  return XRE_IsParentProcess();
}

void gfxPrefs::PrefAddVarCache(bool* aVariable,
                               const char* aPref,
                               bool aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::AddBoolVarCache(aVariable, aPref, aDefault);
}

void gfxPrefs::PrefAddVarCache(int32_t* aVariable,
                               const char* aPref,
                               int32_t aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::AddIntVarCache(aVariable, aPref, aDefault);
}

void gfxPrefs::PrefAddVarCache(uint32_t* aVariable,
                               const char* aPref,
                               uint32_t aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::AddUintVarCache(aVariable, aPref, aDefault);
}

void gfxPrefs::PrefAddVarCache(float* aVariable,
                               const char* aPref,
                               float aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::AddFloatVarCache(aVariable, aPref, aDefault);
}

void gfxPrefs::PrefAddVarCache(std::string* aVariable,
                               const char* aPref,
                               std::string aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::SetCString(aPref, aVariable->c_str());
}

void gfxPrefs::PrefAddVarCache(AtomicBool* aVariable,
                               const char* aPref,
                               bool aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::AddAtomicBoolVarCache(aVariable, aPref, aDefault);
}

void gfxPrefs::PrefAddVarCache(AtomicInt32* aVariable,
                               const char* aPref,
                               int32_t aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::AddAtomicIntVarCache(aVariable, aPref, aDefault);
}

void gfxPrefs::PrefAddVarCache(AtomicUint32* aVariable,
                               const char* aPref,
                               uint32_t aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::AddAtomicUintVarCache(aVariable, aPref, aDefault);
}

bool gfxPrefs::PrefGet(const char* aPref, bool aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  return Preferences::GetBool(aPref, aDefault);
}

int32_t gfxPrefs::PrefGet(const char* aPref, int32_t aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  return Preferences::GetInt(aPref, aDefault);
}

uint32_t gfxPrefs::PrefGet(const char* aPref, uint32_t aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  return Preferences::GetUint(aPref, aDefault);
}

float gfxPrefs::PrefGet(const char* aPref, float aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  return Preferences::GetFloat(aPref, aDefault);
}

std::string gfxPrefs::PrefGet(const char* aPref, std::string aDefault)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());

  nsAutoCString result;
  Preferences::GetCString(aPref, result);

  if (result.IsEmpty()) {
    return aDefault;
  }

  return result.get();
}

void gfxPrefs::PrefSet(const char* aPref, bool aValue)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::SetBool(aPref, aValue);
}

void gfxPrefs::PrefSet(const char* aPref, int32_t aValue)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::SetInt(aPref, aValue);
}

void gfxPrefs::PrefSet(const char* aPref, uint32_t aValue)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::SetUint(aPref, aValue);
}

void gfxPrefs::PrefSet(const char* aPref, float aValue)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::SetFloat(aPref, aValue);
}

void gfxPrefs::PrefSet(const char* aPref, std::string aValue)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::SetCString(aPref, aValue.c_str());
}

static void
OnGfxPrefChanged(const char* aPrefname, void* aClosure)
{
  reinterpret_cast<gfxPrefs::Pref*>(aClosure)->OnChange();
}

void gfxPrefs::WatchChanges(const char* aPrefname, Pref* aPref)
{
  MOZ_ASSERT(IsPrefsServiceAvailable());
  Preferences::RegisterCallback(OnGfxPrefChanged, aPrefname, aPref);
}

void gfxPrefs::UnwatchChanges(const char* aPrefname, Pref* aPref)
{
  // The Preferences service can go offline before gfxPrefs is destroyed.
  if (IsPrefsServiceAvailable()) {
    Preferences::UnregisterCallback(OnGfxPrefChanged, aPrefname, aPref);
  }
}

void gfxPrefs::CopyPrefValue(const bool* aValue, GfxPrefValue* aOutValue)
{
  *aOutValue = *aValue;
}

void gfxPrefs::CopyPrefValue(const int32_t* aValue, GfxPrefValue* aOutValue)
{
  *aOutValue = *aValue;
}

void gfxPrefs::CopyPrefValue(const uint32_t* aValue, GfxPrefValue* aOutValue)
{
  *aOutValue = *aValue;
}

void gfxPrefs::CopyPrefValue(const float* aValue, GfxPrefValue* aOutValue)
{
  *aOutValue = *aValue;
}

void gfxPrefs::CopyPrefValue(const std::string* aValue, GfxPrefValue* aOutValue)
{
  *aOutValue = nsCString(aValue->c_str());
}

void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, bool* aOutValue)
{
  *aOutValue = aValue->get_bool();
}

void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, int32_t* aOutValue)
{
  *aOutValue = aValue->get_int32_t();
}

void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, uint32_t* aOutValue)
{
  *aOutValue = aValue->get_uint32_t();
}

void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, float* aOutValue)
{
  *aOutValue = aValue->get_float();
}

void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, std::string* aOutValue)
{
  *aOutValue = aValue->get_nsCString().get();
}

bool gfxPrefs::OverrideBase_WebRender()
{
  return gfx::gfxVars::UseWebRender();
}