DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (56e7b9127e89)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
/* -*- 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/. */

#ifndef mozilla_image_FrameTimeout_h
#define mozilla_image_FrameTimeout_h

#include <stdint.h>
#include "mozilla/Assertions.h"

namespace mozilla {
namespace image {

/**
 * FrameTimeout wraps a frame timeout value (measured in milliseconds) after
 * first normalizing it. This normalization is necessary because some tools
 * generate incorrect frame timeout values which we nevertheless have to
 * support. For this reason, code that deals with frame timeouts should always
 * use a FrameTimeout value rather than the raw value from the image header.
 */
struct FrameTimeout
{
  /**
   * @return a FrameTimeout of zero. This should be used only for math
   * involving FrameTimeout values. You can't obtain a zero FrameTimeout from
   * FromRawMilliseconds().
   */
  static FrameTimeout Zero() { return FrameTimeout(0); }

  /// @return an infinite FrameTimeout.
  static FrameTimeout Forever() { return FrameTimeout(-1); }

  /// @return a FrameTimeout obtained by normalizing a raw timeout value.
  static FrameTimeout FromRawMilliseconds(int32_t aRawMilliseconds)
  {
    // Normalize all infinite timeouts to the same value.
    if (aRawMilliseconds < 0) {
      return FrameTimeout::Forever();
    }

    // Very small timeout values are problematic for two reasons: we don't want
    // to burn energy redrawing animated images extremely fast, and broken tools
    // generate these values when they actually want a "default" value, so such
    // images won't play back right without normalization. For some context,
    // see bug 890743, bug 125137, bug 139677, and bug 207059. The historical
    // behavior of IE and Opera was:
    //   IE 6/Win:
    //     10 - 50ms is normalized to 100ms.
    //     >50ms is used unnormalized.
    //   Opera 7 final/Win:
    //     10ms is normalized to 100ms.
    //     >10ms is used unnormalized.
    if (aRawMilliseconds >= 0 && aRawMilliseconds <= 10 ) {
      return FrameTimeout(100);
    }

    // The provided timeout value is OK as-is.
    return FrameTimeout(aRawMilliseconds);
  }

  bool operator==(const FrameTimeout& aOther) const
  {
    return mTimeout == aOther.mTimeout;
  }

  bool operator!=(const FrameTimeout& aOther) const { return !(*this == aOther); }

  FrameTimeout operator+(const FrameTimeout& aOther)
  {
    if (*this == Forever() || aOther == Forever()) {
      return Forever();
    }

    return FrameTimeout(mTimeout + aOther.mTimeout);
  }

  FrameTimeout& operator+=(const FrameTimeout& aOther)
  {
    *this = *this + aOther;
    return *this;
  }

  /**
   * @return this FrameTimeout's value in milliseconds. Illegal to call on a
   * an infinite FrameTimeout value.
   */
  uint32_t AsMilliseconds() const
  {
    if (*this == Forever()) {
      MOZ_ASSERT_UNREACHABLE("Calling AsMilliseconds() on an infinite FrameTimeout");
      return 100;  // Fail to something sane.
    }

    return uint32_t(mTimeout);
  }

  /**
   * @return this FrameTimeout value encoded so that non-negative values
   * represent a timeout in milliseconds, and -1 represents an infinite
   * timeout.
   *
   * XXX(seth): This is a backwards compatibility hack that should be removed.
   */
  int32_t AsEncodedValueDeprecated() const { return mTimeout; }

private:
  explicit FrameTimeout(int32_t aTimeout)
    : mTimeout(aTimeout)
  { }

  int32_t mTimeout;
};

} // namespace image
} // namespace mozilla

#endif // mozilla_image_FrameTimeout_h