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 "FrameUniformityData.h"
7 :
8 : #include <map>
9 :
10 : #include "Units.h"
11 : #include "gfxPoint.h"
12 : #include "mozilla/TimeStamp.h"
13 : #include "mozilla/dom/APZTestDataBinding.h"
14 : #include "mozilla/dom/ToJSValue.h"
15 : #include "nsTArray.h"
16 :
17 : namespace mozilla {
18 : namespace layers {
19 :
20 : using namespace gfx;
21 :
22 : Point
23 0 : LayerTransforms::GetAverage()
24 : {
25 0 : MOZ_ASSERT(!mTransforms.IsEmpty());
26 :
27 0 : Point current = mTransforms[0];
28 0 : Point average;
29 0 : size_t length = mTransforms.Length();
30 :
31 0 : for (size_t i = 1; i < length; i++) {
32 0 : Point nextTransform = mTransforms[i];
33 0 : Point movement = nextTransform - current;
34 0 : average += Point(std::fabs(movement.x), std::fabs(movement.y));
35 0 : current = nextTransform;
36 : }
37 :
38 0 : average = average / (float) length;
39 0 : return average;
40 : }
41 :
42 : Point
43 0 : LayerTransforms::GetStdDev()
44 : {
45 0 : Point average = GetAverage();
46 0 : Point stdDev;
47 0 : Point current = mTransforms[0];
48 :
49 0 : for (size_t i = 1; i < mTransforms.Length(); i++) {
50 0 : Point next = mTransforms[i];
51 0 : Point move = next - current;
52 0 : move.x = fabs(move.x);
53 0 : move.y = fabs(move.y);
54 :
55 0 : Point diff = move - average;
56 0 : diff.x = diff.x * diff.x;
57 0 : diff.y = diff.y * diff.y;
58 0 : stdDev += diff;
59 :
60 0 : current = next;
61 : }
62 :
63 0 : stdDev = stdDev / mTransforms.Length();
64 0 : stdDev.x = sqrt(stdDev.x);
65 0 : stdDev.y = sqrt(stdDev.y);
66 0 : return stdDev;
67 : }
68 :
69 0 : LayerTransformRecorder::~LayerTransformRecorder()
70 : {
71 0 : Reset();
72 0 : }
73 :
74 : void
75 0 : LayerTransformRecorder::RecordTransform(Layer* aLayer, const Point& aTransform)
76 : {
77 0 : LayerTransforms* layerTransforms = GetLayerTransforms((uintptr_t) aLayer);
78 0 : layerTransforms->mTransforms.AppendElement(aTransform);
79 0 : }
80 :
81 : void
82 0 : LayerTransformRecorder::EndTest(FrameUniformityData* aOutData)
83 : {
84 0 : for (auto iter = mFrameTransforms.begin(); iter != mFrameTransforms.end(); ++iter) {
85 0 : uintptr_t layer = iter->first;
86 0 : float uniformity = CalculateFrameUniformity(layer);
87 :
88 0 : std::pair<uintptr_t,float> result(layer, uniformity);
89 0 : aOutData->mUniformities.insert(result);
90 : }
91 :
92 0 : Reset();
93 0 : }
94 :
95 : LayerTransforms*
96 0 : LayerTransformRecorder::GetLayerTransforms(uintptr_t aLayer)
97 : {
98 0 : if (!mFrameTransforms.count(aLayer)) {
99 0 : LayerTransforms* newTransform = new LayerTransforms();
100 0 : std::pair<uintptr_t, LayerTransforms*> newLayer(aLayer, newTransform);
101 0 : mFrameTransforms.insert(newLayer);
102 : }
103 :
104 0 : return mFrameTransforms.find(aLayer)->second;
105 : }
106 :
107 : void
108 0 : LayerTransformRecorder::Reset()
109 : {
110 0 : for (auto iter = mFrameTransforms.begin(); iter != mFrameTransforms.end(); ++iter) {
111 0 : LayerTransforms* layerTransforms = iter->second;
112 0 : delete layerTransforms;
113 : }
114 :
115 0 : mFrameTransforms.clear();
116 0 : }
117 :
118 : float
119 0 : LayerTransformRecorder::CalculateFrameUniformity(uintptr_t aLayer)
120 : {
121 0 : LayerTransforms* layerTransform = GetLayerTransforms(aLayer);
122 0 : float yUniformity = -1;
123 0 : if (!layerTransform->mTransforms.IsEmpty()) {
124 0 : Point stdDev = layerTransform->GetStdDev();
125 0 : yUniformity = stdDev.y;
126 : }
127 0 : return yUniformity;
128 : }
129 :
130 : bool
131 0 : FrameUniformityData::ToJS(JS::MutableHandleValue aOutValue, JSContext* aContext)
132 : {
133 0 : dom::FrameUniformityResults results;
134 0 : dom::Sequence<dom::FrameUniformity>& layers = results.mLayerUniformities.Construct();
135 :
136 0 : for (auto iter = mUniformities.begin(); iter != mUniformities.end(); ++iter) {
137 0 : uintptr_t layerAddr = iter->first;
138 0 : float uniformity = iter->second;
139 :
140 : // FIXME: Make this infallible after bug 968520 is done.
141 0 : MOZ_ALWAYS_TRUE(layers.AppendElement(fallible));
142 0 : dom::FrameUniformity& entry = layers.LastElement();
143 :
144 0 : entry.mLayerAddress.Construct() = layerAddr;
145 0 : entry.mFrameUniformity.Construct() = uniformity;
146 : }
147 :
148 0 : return dom::ToJSValue(aContext, results, aOutValue);
149 : }
150 :
151 : } // namespace layers
152 : } // namespace mozilla
|