gfxVars.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "gfxVars.h"
  6. #include "gfxVarReceiver.h"
  7. #include "mozilla/dom/ContentChild.h"
  8. namespace mozilla {
  9. namespace gfx {
  10. StaticAutoPtr<gfxVars> gfxVars::sInstance;
  11. StaticAutoPtr<nsTArray<gfxVars::VarBase*>> gfxVars::sVarList;
  12. void
  13. gfxVars::Initialize()
  14. {
  15. if (sInstance) {
  16. return;
  17. }
  18. // sVarList must be initialized first since it's used in the constructor for
  19. // sInstance.
  20. sVarList = new nsTArray<gfxVars::VarBase*>();
  21. sInstance = new gfxVars;
  22. // Like Preferences, we want content to synchronously get initial data on
  23. // init. Note the GPU process is not handled here - it cannot send sync
  24. // messages, so instead the initial data is pushed down.
  25. if (XRE_IsContentProcess()) {
  26. InfallibleTArray<GfxVarUpdate> vars;
  27. dom::ContentChild::GetSingleton()->SendGetGfxVars(&vars);
  28. for (const auto& var : vars) {
  29. ApplyUpdate(var);
  30. }
  31. }
  32. }
  33. gfxVars::gfxVars()
  34. {
  35. }
  36. void
  37. gfxVars::Shutdown()
  38. {
  39. sInstance = nullptr;
  40. sVarList = nullptr;
  41. }
  42. /* static */ void
  43. gfxVars::ApplyUpdate(const GfxVarUpdate& aUpdate)
  44. {
  45. // Only subprocesses receive updates and apply them locally.
  46. MOZ_ASSERT(!XRE_IsParentProcess());
  47. sVarList->ElementAt(aUpdate.index())->SetValue(aUpdate.value());
  48. }
  49. /* static */ void
  50. gfxVars::AddReceiver(gfxVarReceiver* aReceiver)
  51. {
  52. MOZ_ASSERT(NS_IsMainThread());
  53. // Don't double-add receivers, in case a broken content process sends two
  54. // init messages.
  55. if (!sInstance->mReceivers.Contains(aReceiver)) {
  56. sInstance->mReceivers.AppendElement(aReceiver);
  57. }
  58. }
  59. /* static */ void
  60. gfxVars::RemoveReceiver(gfxVarReceiver* aReceiver)
  61. {
  62. MOZ_ASSERT(NS_IsMainThread());
  63. if (sInstance) {
  64. sInstance->mReceivers.RemoveElement(aReceiver);
  65. }
  66. }
  67. /* static */ nsTArray<GfxVarUpdate>
  68. gfxVars::FetchNonDefaultVars()
  69. {
  70. MOZ_ASSERT(NS_IsMainThread());
  71. MOZ_ASSERT(sVarList);
  72. nsTArray<GfxVarUpdate> updates;
  73. for (size_t i = 0; i < sVarList->Length(); i++) {
  74. VarBase* var = sVarList->ElementAt(i);
  75. if (var->HasDefaultValue()) {
  76. continue;
  77. }
  78. GfxVarValue value;
  79. var->GetValue(&value);
  80. updates.AppendElement(GfxVarUpdate(i, value));
  81. }
  82. return updates;
  83. }
  84. gfxVars::VarBase::VarBase()
  85. {
  86. mIndex = gfxVars::sVarList->Length();
  87. gfxVars::sVarList->AppendElement(this);
  88. }
  89. void
  90. gfxVars::NotifyReceivers(VarBase* aVar)
  91. {
  92. MOZ_ASSERT(NS_IsMainThread());
  93. GfxVarValue value;
  94. aVar->GetValue(&value);
  95. GfxVarUpdate update(aVar->Index(), value);
  96. for (auto& receiver : mReceivers) {
  97. receiver->OnVarChanged(update);
  98. }
  99. }
  100. } // namespace gfx
  101. } // namespace mozilla