widget/VsyncDispatcher.cpp
author Doug Turner <doug.turner@gmail.com>
Tue, 03 Feb 2015 17:00:00 +0100
changeset 243715 840987c23fc597bdaad4567c2387ba1aa06c65d0
parent 241262 7ab92d922d193944248a608e961598e1cb6a000f
child 246236 f88dedd047aed1171270aa3d3eef8e6225d6a36b
permissions -rw-r--r--
Bug 1045229 - Beacons are not associated with windows. The current window based filtering that the network monitor does will skip requests that come from sendBeacon(). Here we explictly look to see if the network channel is from beacon by looking at the loadinfo. r=dcamp, a=sledru

/* -*- Mode: C++; tab-width: 2; 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 "VsyncDispatcher.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/layers/CompositorParent.h"
#include "gfxPrefs.h"

#ifdef MOZ_ENABLE_PROFILER_SPS
#include "GeckoProfiler.h"
#include "ProfilerMarkers.h"
#endif

#ifdef MOZ_WIDGET_GONK
#include "GeckoTouchDispatcher.h"
#endif

using namespace mozilla::layers;

namespace mozilla {

StaticRefPtr<VsyncDispatcher> sVsyncDispatcher;

/*static*/ VsyncDispatcher*
VsyncDispatcher::GetInstance()
{
  if (!sVsyncDispatcher) {
    sVsyncDispatcher = new VsyncDispatcher();
    ClearOnShutdown(&sVsyncDispatcher);
  }

  return sVsyncDispatcher;
}

VsyncDispatcher::VsyncDispatcher()
  : mCompositorObserverLock("CompositorObserverLock")
{

}

VsyncDispatcher::~VsyncDispatcher()
{
  MutexAutoLock lock(mCompositorObserverLock);
  mCompositorObservers.Clear();
}

void
VsyncDispatcher::SetVsyncSource(VsyncSource* aVsyncSource)
{
  mVsyncSource = aVsyncSource;
}

void
VsyncDispatcher::DispatchTouchEvents(bool aNotifiedCompositors, TimeStamp aVsyncTime)
{
  // Touch events can sometimes start a composite, so make sure we dispatch touches
  // even if we don't composite
#ifdef MOZ_WIDGET_GONK
  if (!aNotifiedCompositors && gfxPrefs::TouchResampling()) {
    GeckoTouchDispatcher::NotifyVsync(aVsyncTime);
  }
#endif
}

void
VsyncDispatcher::NotifyVsync(TimeStamp aVsyncTimestamp)
{
  bool notifiedCompositors = false;
#ifdef MOZ_ENABLE_PROFILER_SPS
    if (profiler_is_active()) {
        CompositorParent::PostInsertVsyncProfilerMarker(aVsyncTimestamp);
    }
#endif

  if (gfxPrefs::VsyncAlignedCompositor()) {
    MutexAutoLock lock(mCompositorObserverLock);
    notifiedCompositors = NotifyVsyncObservers(aVsyncTimestamp, mCompositorObservers);
  }

  DispatchTouchEvents(notifiedCompositors, aVsyncTimestamp);
}

bool
VsyncDispatcher::NotifyVsyncObservers(TimeStamp aVsyncTimestamp, nsTArray<nsRefPtr<VsyncObserver>>& aObservers)
{
  // Callers should lock the respective lock for the aObservers before calling this function
  for (size_t i = 0; i < aObservers.Length(); i++) {
    aObservers[i]->NotifyVsync(aVsyncTimestamp);
 }
 return !aObservers.IsEmpty();
}

void
VsyncDispatcher::AddCompositorVsyncObserver(VsyncObserver* aVsyncObserver)
{
  MOZ_ASSERT(CompositorParent::IsInCompositorThread());
  MutexAutoLock lock(mCompositorObserverLock);
  if (!mCompositorObservers.Contains(aVsyncObserver)) {
    mCompositorObservers.AppendElement(aVsyncObserver);
  }
}

void
VsyncDispatcher::RemoveCompositorVsyncObserver(VsyncObserver* aVsyncObserver)
{
  MOZ_ASSERT(CompositorParent::IsInCompositorThread() || NS_IsMainThread());
  MutexAutoLock lock(mCompositorObserverLock);
  if (mCompositorObservers.Contains(aVsyncObserver)) {
    mCompositorObservers.RemoveElement(aVsyncObserver);
  } else {
    NS_WARNING("Could not delete a compositor vsync observer\n");
  }
}

} // namespace mozilla