Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/image/FrameTimeout.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
 *
3
 * This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_image_FrameTimeout_h
8
#define mozilla_image_FrameTimeout_h
9
10
#include <stdint.h>
11
#include "mozilla/Assertions.h"
12
13
namespace mozilla {
14
namespace image {
15
16
/**
17
 * FrameTimeout wraps a frame timeout value (measured in milliseconds) after
18
 * first normalizing it. This normalization is necessary because some tools
19
 * generate incorrect frame timeout values which we nevertheless have to
20
 * support. For this reason, code that deals with frame timeouts should always
21
 * use a FrameTimeout value rather than the raw value from the image header.
22
 */
23
struct FrameTimeout
24
{
25
  /**
26
   * @return a FrameTimeout of zero. This should be used only for math
27
   * involving FrameTimeout values. You can't obtain a zero FrameTimeout from
28
   * FromRawMilliseconds().
29
   */
30
0
  static FrameTimeout Zero() { return FrameTimeout(0); }
31
32
  /// @return an infinite FrameTimeout.
33
0
  static FrameTimeout Forever() { return FrameTimeout(-1); }
34
35
  /// @return a FrameTimeout obtained by normalizing a raw timeout value.
36
  static FrameTimeout FromRawMilliseconds(int32_t aRawMilliseconds)
37
0
  {
38
0
    // Normalize all infinite timeouts to the same value.
39
0
    if (aRawMilliseconds < 0) {
40
0
      return FrameTimeout::Forever();
41
0
    }
42
0
43
0
    // Very small timeout values are problematic for two reasons: we don't want
44
0
    // to burn energy redrawing animated images extremely fast, and broken tools
45
0
    // generate these values when they actually want a "default" value, so such
46
0
    // images won't play back right without normalization. For some context,
47
0
    // see bug 890743, bug 125137, bug 139677, and bug 207059. The historical
48
0
    // behavior of IE and Opera was:
49
0
    //   IE 6/Win:
50
0
    //     10 - 50ms is normalized to 100ms.
51
0
    //     >50ms is used unnormalized.
52
0
    //   Opera 7 final/Win:
53
0
    //     10ms is normalized to 100ms.
54
0
    //     >10ms is used unnormalized.
55
0
    if (aRawMilliseconds >= 0 && aRawMilliseconds <= 10 ) {
56
0
      return FrameTimeout(100);
57
0
    }
58
0
59
0
    // The provided timeout value is OK as-is.
60
0
    return FrameTimeout(aRawMilliseconds);
61
0
  }
62
63
  bool operator==(const FrameTimeout& aOther) const
64
0
  {
65
0
    return mTimeout == aOther.mTimeout;
66
0
  }
67
68
0
  bool operator!=(const FrameTimeout& aOther) const { return !(*this == aOther); }
69
70
  FrameTimeout operator+(const FrameTimeout& aOther)
71
0
  {
72
0
    if (*this == Forever() || aOther == Forever()) {
73
0
      return Forever();
74
0
    }
75
0
76
0
    return FrameTimeout(mTimeout + aOther.mTimeout);
77
0
  }
78
79
  FrameTimeout& operator+=(const FrameTimeout& aOther)
80
0
  {
81
0
    *this = *this + aOther;
82
0
    return *this;
83
0
  }
84
85
  /**
86
   * @return this FrameTimeout's value in milliseconds. Illegal to call on a
87
   * an infinite FrameTimeout value.
88
   */
89
  uint32_t AsMilliseconds() const
90
0
  {
91
0
    if (*this == Forever()) {
92
0
      MOZ_ASSERT_UNREACHABLE("Calling AsMilliseconds() on an infinite FrameTimeout");
93
0
      return 100;  // Fail to something sane.
94
0
    }
95
0
96
0
    return uint32_t(mTimeout);
97
0
  }
98
99
  /**
100
   * @return this FrameTimeout value encoded so that non-negative values
101
   * represent a timeout in milliseconds, and -1 represents an infinite
102
   * timeout.
103
   *
104
   * XXX(seth): This is a backwards compatibility hack that should be removed.
105
   */
106
0
  int32_t AsEncodedValueDeprecated() const { return mTimeout; }
107
108
private:
109
  explicit FrameTimeout(int32_t aTimeout)
110
    : mTimeout(aTimeout)
111
0
  { }
112
113
  int32_t mTimeout;
114
};
115
116
} // namespace image
117
} // namespace mozilla
118
119
#endif // mozilla_image_FrameTimeout_h