Line data Source code
1 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
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 :
6 : #include "ImageComposite.h"
7 :
8 : namespace mozilla {
9 :
10 : using namespace gfx;
11 :
12 : namespace layers {
13 :
14 : /* static */ const float ImageComposite::BIAS_TIME_MS = 1.0f;
15 :
16 0 : ImageComposite::ImageComposite()
17 : : mLastFrameID(-1)
18 : , mLastProducerID(-1)
19 0 : , mBias(BIAS_NONE)
20 0 : {}
21 :
22 0 : ImageComposite::~ImageComposite()
23 : {
24 0 : }
25 :
26 : /* static */ TimeStamp
27 0 : ImageComposite::GetBiasedTime(const TimeStamp& aInput, ImageComposite::Bias aBias)
28 : {
29 0 : switch (aBias) {
30 : case ImageComposite::BIAS_NEGATIVE:
31 0 : return aInput - TimeDuration::FromMilliseconds(BIAS_TIME_MS);
32 : case ImageComposite::BIAS_POSITIVE:
33 0 : return aInput + TimeDuration::FromMilliseconds(BIAS_TIME_MS);
34 : default:
35 0 : return aInput;
36 : }
37 : }
38 :
39 : /* static */ ImageComposite::Bias
40 0 : ImageComposite::UpdateBias(const TimeStamp& aCompositionTime,
41 : const TimeStamp& aCompositedImageTime,
42 : const TimeStamp& aNextImageTime, // may be null
43 : ImageComposite::Bias aBias)
44 : {
45 0 : if (aCompositedImageTime.IsNull()) {
46 0 : return ImageComposite::BIAS_NONE;
47 : }
48 0 : TimeDuration threshold = TimeDuration::FromMilliseconds(1.0);
49 0 : if (aCompositionTime - aCompositedImageTime < threshold &&
50 0 : aCompositionTime - aCompositedImageTime > -threshold) {
51 : // The chosen frame's time is very close to the composition time (probably
52 : // just before the current composition time, but due to previously set
53 : // negative bias, it could be just after the current composition time too).
54 : // If the inter-frame time is almost exactly equal to (a multiple of)
55 : // the inter-composition time, then we're in a dangerous situation because
56 : // jitter might cause frames to fall one side or the other of the
57 : // composition times, causing many frames to be skipped or duplicated.
58 : // Try to prevent that by adding a negative bias to the frame times during
59 : // the next composite; that should ensure the next frame's time is treated
60 : // as falling just before a composite time.
61 0 : return ImageComposite::BIAS_NEGATIVE;
62 : }
63 0 : if (!aNextImageTime.IsNull() &&
64 0 : aNextImageTime - aCompositionTime < threshold &&
65 0 : aNextImageTime - aCompositionTime > -threshold) {
66 : // The next frame's time is very close to our composition time (probably
67 : // just after the current composition time, but due to previously set
68 : // positive bias, it could be just before the current composition time too).
69 : // We're in a dangerous situation because jitter might cause frames to
70 : // fall one side or the other of the composition times, causing many frames
71 : // to be skipped or duplicated.
72 : // Try to prevent that by adding a negative bias to the frame times during
73 : // the next composite; that should ensure the next frame's time is treated
74 : // as falling just before a composite time.
75 0 : return ImageComposite::BIAS_POSITIVE;
76 : }
77 0 : return ImageComposite::BIAS_NONE;
78 : }
79 :
80 : int
81 0 : ImageComposite::ChooseImageIndex() const
82 : {
83 0 : if (mImages.IsEmpty()) {
84 0 : return -1;
85 : }
86 0 : TimeStamp now = GetCompositionTime();
87 :
88 0 : if (now.IsNull()) {
89 : // Not in a composition, so just return the last image we composited
90 : // (if it's one of the current images).
91 0 : for (uint32_t i = 0; i < mImages.Length(); ++i) {
92 0 : if (mImages[i].mFrameID == mLastFrameID &&
93 0 : mImages[i].mProducerID == mLastProducerID) {
94 0 : return i;
95 : }
96 : }
97 0 : return -1;
98 : }
99 :
100 0 : uint32_t result = 0;
101 0 : while (result + 1 < mImages.Length() &&
102 0 : GetBiasedTime(mImages[result + 1].mTimeStamp, mBias) <= now) {
103 0 : ++result;
104 : }
105 0 : return result;
106 : }
107 :
108 0 : const ImageComposite::TimedImage* ImageComposite::ChooseImage() const
109 : {
110 0 : int index = ChooseImageIndex();
111 0 : return index >= 0 ? &mImages[index] : nullptr;
112 : }
113 :
114 0 : ImageComposite::TimedImage* ImageComposite::ChooseImage()
115 : {
116 0 : int index = ChooseImageIndex();
117 0 : return index >= 0 ? &mImages[index] : nullptr;
118 : }
119 :
120 : } // namespace layers
121 : } // namespace mozilla
|