зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1077651 Measure frame uniformity by synthesizing native events. r=kats,mrbkap
This commit is contained in:
Родитель
0b9c62a5fb
Коммит
920f2ea28a
|
@ -70,7 +70,6 @@
|
|||
#endif
|
||||
|
||||
#include "Layers.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "gfxPrefs.h"
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
@ -82,6 +81,8 @@
|
|||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/quota/PersistenceType.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/layers/FrameUniformityData.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsViewportInfo.h"
|
||||
#include "nsIFormControl.h"
|
||||
|
@ -3716,6 +3717,27 @@ nsDOMWindowUtils::SetChromeMargin(int32_t aTop,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetFrameUniformityTestData(JSContext* aContext,
|
||||
JS::MutableHandleValue aOutFrameUniformity)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
|
||||
nsIWidget* widget = GetWidget();
|
||||
if (!widget) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsRefPtr<LayerManager> manager = widget->GetLayerManager();
|
||||
if (!manager) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
FrameUniformityData outData;
|
||||
manager->GetFrameUniformity(&outData);
|
||||
outData.ToJS(aOutFrameUniformity, aContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::XpconnectArgument(nsIDOMWindowUtils* aThis)
|
||||
{
|
||||
|
|
|
@ -49,7 +49,7 @@ interface nsIJSRAIIHelper;
|
|||
interface nsIContentPermissionRequest;
|
||||
interface nsIObserver;
|
||||
|
||||
[scriptable, uuid(098d9f0d-7809-4d3c-8fc6-e5b3fb71835b)]
|
||||
[scriptable, uuid(ec176f3b-2886-4090-938e-dded103c5f1c)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
|
@ -1814,6 +1814,14 @@ interface nsIDOMWindowUtils : nsISupports {
|
|||
attribute boolean serviceWorkersTestingEnabled;
|
||||
|
||||
/**
|
||||
* Returns a JSObject which contains a list of frame uniformities
|
||||
* when the pref gfx.vsync.collect-scroll-data is enabled.
|
||||
* Every result contains a layer address and a frame uniformity for that layer.
|
||||
* A negative frame uniformity value indicates an invalid frame uniformity and an error has occured.
|
||||
*/
|
||||
[implicit_jscontext] jsval getFrameUniformityTestData();
|
||||
|
||||
/*
|
||||
* Increase the chaos mode activation level. An equivalent number of
|
||||
* calls to leaveChaosMode must be made in order to restore the original
|
||||
* chaos mode state. If the activation level is nonzero all chaos mode
|
||||
|
|
|
@ -35,3 +35,13 @@ dictionary APZTestData {
|
|||
sequence<APZBucket> paints;
|
||||
sequence<APZBucket> repaintRequests;
|
||||
};
|
||||
|
||||
// A frame uniformity measurement for every scrollable layer
|
||||
dictionary FrameUniformity {
|
||||
unsigned long layerAddress;
|
||||
float frameUniformity;
|
||||
};
|
||||
|
||||
dictionary FrameUniformityResults {
|
||||
sequence<FrameUniformity> layerUniformities;
|
||||
};
|
||||
|
|
|
@ -92,6 +92,7 @@ class ShadowLayerForwarder;
|
|||
class LayerManagerComposite;
|
||||
class SpecificLayerAttributes;
|
||||
class Compositor;
|
||||
class FrameUniformityData;
|
||||
|
||||
namespace layerscope {
|
||||
class LayersPacket;
|
||||
|
@ -643,6 +644,7 @@ public:
|
|||
virtual bool IsCompositingCheap() { return true; }
|
||||
|
||||
bool IsInTransaction() const { return mInTransaction; }
|
||||
virtual void GetFrameUniformity(FrameUniformityData* aOutData) { }
|
||||
virtual bool RequestOverfill(mozilla::dom::OverfillCallback* aCallback) { return true; }
|
||||
virtual void RunOverfillCallback(const uint32_t aOverfill) { }
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
apz_test_native_event_utils.js
|
||||
tags = apz-chrome
|
||||
|
||||
[test_smoothness.html]
|
||||
# hardware vsync only on win/mac
|
||||
# e10s only since APZ is only enabled on e10s
|
||||
skip-if = debug || (os != 'mac' && os != 'win') || !e10s
|
|
@ -0,0 +1,83 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Test Frame Uniformity While Scrolling</title>
|
||||
<script type="text/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||
|
||||
<style>
|
||||
#content {
|
||||
height: 5000px;
|
||||
background: repeating-linear-gradient(#EEE, #EEE 100px, #DDD 100px, #DDD 200px);
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
var scrollEvents = 100;
|
||||
var i = 0;
|
||||
var testPref = "gfx.vsync.collect-scroll-transforms";
|
||||
// Scroll points
|
||||
var x = 100;
|
||||
var y = 150;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var utils = _getDOMWindowUtils(window);
|
||||
|
||||
function sendScrollEvent(aRafTimestamp) {
|
||||
var scrollDiv = document.getElementById("content");
|
||||
|
||||
if (i < scrollEvents) {
|
||||
i++;
|
||||
// Scroll diff
|
||||
var dx = 0;
|
||||
var dy = -10; // Negative to scroll down
|
||||
synthesizeNativeWheelAndWaitForEvent(scrollDiv, x, y, dx, dy);
|
||||
window.requestAnimationFrame(sendScrollEvent);
|
||||
} else {
|
||||
// Locally, with silk and apz + e10s, retina 15" mbp usually get ~1.0 - 1.5
|
||||
// w/o silk + e10s + apz, I get up to 7. Lower is better.
|
||||
// Windows, I get ~3. Values are not valid w/o hardware vsync
|
||||
var uniformities = _getDOMWindowUtils().getFrameUniformityTestData();
|
||||
for (var j = 0; j < uniformities.layerUniformities.length; j++) {
|
||||
var layerResult = uniformities.layerUniformities[j];
|
||||
var layerAddr = layerResult.layerAddress;
|
||||
var uniformity = layerResult.frameUniformity;
|
||||
var msg = "Layer: " + layerAddr.toString(16) + " Uniformity: " + uniformity;
|
||||
SimpleTest.ok((uniformity >= 0) && (uniformity < 4.0), msg);
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
window.requestAnimationFrame(sendScrollEvent);
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
var apzEnabled = SpecialPowers.getBoolPref("layers.async-pan-zoom.enabled");
|
||||
if (!apzEnabled) {
|
||||
SimpleTest.ok(true, "APZ not enabled, skipping test");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
var hwVsyncEnabled = SpecialPowers.getBoolPref("gfx.vsync.hw-vsync.enabled");
|
||||
if (!hwVsyncEnabled) {
|
||||
SimpleTest.ok(true, "Hardware vsync not enabled, skipping test");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set" : [
|
||||
[testPref, true]
|
||||
]
|
||||
}, startTest);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="content">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/layers/CompositableClient.h"
|
||||
#include "mozilla/layers/CompositorChild.h" // for CompositorChild
|
||||
#include "mozilla/layers/ContentClient.h"
|
||||
#include "mozilla/layers/FrameUniformityData.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "mozilla/layers/LayersMessages.h" // for EditReply, etc
|
||||
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
|
||||
|
@ -426,6 +427,20 @@ ClientLayerManager::StartNewRepaintRequest(SequenceNumber aSequenceNumber)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ClientLayerManager::GetFrameUniformity(FrameUniformityData* aOutData)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess(), "Frame Uniformity only supported in parent process");
|
||||
|
||||
if (HasShadowManager()) {
|
||||
CompositorChild* child = GetRemoteRenderer();
|
||||
child->SendGetFrameUniformity(aOutData);
|
||||
return;
|
||||
}
|
||||
|
||||
return LayerManager::GetFrameUniformity(aOutData);
|
||||
}
|
||||
|
||||
bool
|
||||
ClientLayerManager::RequestOverfill(mozilla::dom::OverfillCallback* aCallback)
|
||||
{
|
||||
|
|
|
@ -34,6 +34,7 @@ class ClientPaintedLayer;
|
|||
class CompositorChild;
|
||||
class ImageLayer;
|
||||
class PLayerChild;
|
||||
class FrameUniformityData;
|
||||
class TextureClientPool;
|
||||
|
||||
class ClientLayerManager final : public LayerManager
|
||||
|
@ -200,6 +201,7 @@ public:
|
|||
bool NeedsComposite() const { return mNeedsComposite; }
|
||||
|
||||
virtual void Composite() override;
|
||||
virtual void GetFrameUniformity(FrameUniformityData* aFrameUniformityData) override;
|
||||
virtual bool RequestOverfill(mozilla::dom::OverfillCallback* aCallback) override;
|
||||
virtual void RunOverfillCallback(const uint32_t aOverfill) override;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
# include "AndroidBridge.h"
|
||||
#endif
|
||||
#include "GeckoProfiler.h"
|
||||
#include "FrameUniformityData.h"
|
||||
|
||||
struct nsCSSValueSharedList;
|
||||
|
||||
|
@ -94,6 +95,18 @@ WalkTheTree(Layer* aLayer,
|
|||
}
|
||||
}
|
||||
|
||||
AsyncCompositionManager::AsyncCompositionManager(LayerManagerComposite* aManager)
|
||||
: mLayerManager(aManager)
|
||||
, mIsFirstPaint(true)
|
||||
, mLayersUpdated(false)
|
||||
, mReadyForCompose(true)
|
||||
{
|
||||
}
|
||||
|
||||
AsyncCompositionManager::~AsyncCompositionManager()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
AsyncCompositionManager::ResolveRefLayers()
|
||||
{
|
||||
|
@ -545,6 +558,36 @@ SampleAPZAnimations(const LayerMetricsWrapper& aLayer, TimeStamp aSampleTime)
|
|||
return activeAnimations;
|
||||
}
|
||||
|
||||
void
|
||||
AsyncCompositionManager::RecordShadowTransforms(Layer* aLayer)
|
||||
{
|
||||
MOZ_ASSERT(gfxPrefs::CollectScrollTransforms());
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
|
||||
for (Layer* child = aLayer->GetFirstChild();
|
||||
child; child = child->GetNextSibling()) {
|
||||
RecordShadowTransforms(child);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aLayer->GetFrameMetricsCount(); i++) {
|
||||
AsyncPanZoomController* apzc = aLayer->GetAsyncPanZoomController(i);
|
||||
if (!apzc) {
|
||||
continue;
|
||||
}
|
||||
gfx::Matrix4x4 shadowTransform = aLayer->AsLayerComposite()->GetShadowTransform();
|
||||
if (!shadowTransform.Is2D()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Matrix transform = shadowTransform.As2D();
|
||||
if (transform.IsTranslation() && !shadowTransform.IsIdentity()) {
|
||||
Point translation = transform.GetTranslation();
|
||||
mLayerTransformRecorder.RecordTransform(aLayer, translation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Matrix4x4
|
||||
AdjustForClip(const Matrix4x4& asyncTransform, Layer* aLayer)
|
||||
{
|
||||
|
@ -1051,6 +1094,13 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
|
|||
aLayer->GetLocalTransform(), fixedLayerMargins);
|
||||
}
|
||||
|
||||
void
|
||||
AsyncCompositionManager::GetFrameUniformity(FrameUniformityData* aOutData)
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
mLayerTransformRecorder.EndTest(aOutData);
|
||||
}
|
||||
|
||||
bool
|
||||
AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
|
||||
TransformsToSkip aSkip)
|
||||
|
@ -1103,6 +1153,9 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame,
|
|||
trans *= gfx::Matrix4x4::From2D(mWorldTransform);
|
||||
rootComposite->SetShadowTransform(trans);
|
||||
|
||||
if (gfxPrefs::CollectScrollTransforms()) {
|
||||
RecordShadowTransforms(root);
|
||||
}
|
||||
|
||||
return wantNextFrame;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/dom/ScreenOrientation.h" // for ScreenOrientation
|
||||
#include "mozilla/gfx/BasePoint.h" // for BasePoint
|
||||
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
|
||||
#include "mozilla/layers/FrameUniformityData.h" // For FrameUniformityData
|
||||
#include "mozilla/layers/LayersMessages.h" // for TargetConfig
|
||||
#include "nsRefPtr.h" // for nsRefPtr
|
||||
#include "nsISupportsImpl.h" // for LayerManager::AddRef, etc
|
||||
|
@ -70,19 +71,12 @@ struct ViewTransform {
|
|||
class AsyncCompositionManager final
|
||||
{
|
||||
friend class AutoResolveRefLayers;
|
||||
~AsyncCompositionManager()
|
||||
{
|
||||
}
|
||||
~AsyncCompositionManager();
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(AsyncCompositionManager)
|
||||
|
||||
explicit AsyncCompositionManager(LayerManagerComposite* aManager)
|
||||
: mLayerManager(aManager)
|
||||
, mIsFirstPaint(true)
|
||||
, mLayersUpdated(false)
|
||||
, mReadyForCompose(true)
|
||||
{
|
||||
}
|
||||
explicit AsyncCompositionManager(LayerManagerComposite* aManager);
|
||||
|
||||
/**
|
||||
* This forces the is-first-paint flag to true. This is intended to
|
||||
|
@ -123,6 +117,10 @@ public:
|
|||
// particular document.
|
||||
bool IsFirstPaint() { return mIsFirstPaint; }
|
||||
|
||||
// GetFrameUniformity will return the frame uniformity for each layer attached to an APZ
|
||||
// from the recorded data in RecordShadowTransform
|
||||
void GetFrameUniformity(FrameUniformityData* aFrameUniformityData);
|
||||
|
||||
private:
|
||||
void TransformScrollableLayer(Layer* aLayer);
|
||||
// Return true if an AsyncPanZoomController content transform was
|
||||
|
@ -190,6 +188,9 @@ private:
|
|||
*/
|
||||
void DetachRefLayers();
|
||||
|
||||
// Records the shadow transforms for the tree of layers rooted at the given layer
|
||||
void RecordShadowTransforms(Layer* aLayer);
|
||||
|
||||
TargetConfig mTargetConfig;
|
||||
CSSRect mContentRect;
|
||||
|
||||
|
@ -208,6 +209,7 @@ private:
|
|||
bool mReadyForCompose;
|
||||
|
||||
gfx::Matrix mWorldTransform;
|
||||
LayerTransformRecorder mLayerTransformRecorder;
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AsyncCompositionManager::TransformsToSkip)
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/* -*- Mode: C++; tab-width: 20; 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 "FrameUniformityData.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "Units.h"
|
||||
#include "gfxPoint.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/dom/APZTestDataBinding.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
Point
|
||||
LayerTransforms::GetAverage()
|
||||
{
|
||||
MOZ_ASSERT(!mTransforms.IsEmpty());
|
||||
|
||||
Point current = mTransforms[0];
|
||||
Point average;
|
||||
size_t length = mTransforms.Length();
|
||||
|
||||
for (size_t i = 1; i < length; i++) {
|
||||
Point nextTransform = mTransforms[i];
|
||||
Point movement = nextTransform - current;
|
||||
average += Point(std::fabs(movement.x), std::fabs(movement.y));
|
||||
current = nextTransform;
|
||||
}
|
||||
|
||||
average = average / (float) length;
|
||||
return average;
|
||||
}
|
||||
|
||||
Point
|
||||
LayerTransforms::GetStdDev()
|
||||
{
|
||||
Point average = GetAverage();
|
||||
Point stdDev;
|
||||
Point current = mTransforms[0];
|
||||
|
||||
for (size_t i = 1; i < mTransforms.Length(); i++) {
|
||||
Point next = mTransforms[i];
|
||||
Point move = next - current;
|
||||
move.x = fabs(move.x);
|
||||
move.y = fabs(move.y);
|
||||
|
||||
Point diff = move - average;
|
||||
diff.x = diff.x * diff.x;
|
||||
diff.y = diff.y * diff.y;
|
||||
stdDev += diff;
|
||||
|
||||
current = next;
|
||||
}
|
||||
|
||||
stdDev = stdDev / mTransforms.Length();
|
||||
stdDev.x = sqrt(stdDev.x);
|
||||
stdDev.y = sqrt(stdDev.y);
|
||||
return stdDev;
|
||||
}
|
||||
|
||||
LayerTransformRecorder::~LayerTransformRecorder()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransformRecorder::RecordTransform(Layer* aLayer, const Point& aTransform)
|
||||
{
|
||||
LayerTransforms* layerTransforms = GetLayerTransforms((uintptr_t) aLayer);
|
||||
layerTransforms->mTransforms.AppendElement(aTransform);
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransformRecorder::EndTest(FrameUniformityData* aOutData)
|
||||
{
|
||||
for (auto iter = mFrameTransforms.begin(); iter != mFrameTransforms.end(); ++iter) {
|
||||
uintptr_t layer = iter->first;
|
||||
float uniformity = CalculateFrameUniformity(layer);
|
||||
|
||||
std::pair<uintptr_t,float> result(layer, uniformity);
|
||||
aOutData->mUniformities.insert(result);
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
LayerTransforms*
|
||||
LayerTransformRecorder::GetLayerTransforms(uintptr_t aLayer)
|
||||
{
|
||||
if (!mFrameTransforms.count(aLayer)) {
|
||||
LayerTransforms* newTransform = new LayerTransforms();
|
||||
std::pair<uintptr_t, LayerTransforms*> newLayer(aLayer, newTransform);
|
||||
mFrameTransforms.insert(newLayer);
|
||||
}
|
||||
|
||||
return mFrameTransforms.find(aLayer)->second;
|
||||
}
|
||||
|
||||
void
|
||||
LayerTransformRecorder::Reset()
|
||||
{
|
||||
for (auto iter = mFrameTransforms.begin(); iter != mFrameTransforms.end(); ++iter) {
|
||||
LayerTransforms* layerTransforms = iter->second;
|
||||
delete layerTransforms;
|
||||
}
|
||||
|
||||
mFrameTransforms.clear();
|
||||
}
|
||||
|
||||
float
|
||||
LayerTransformRecorder::CalculateFrameUniformity(uintptr_t aLayer)
|
||||
{
|
||||
LayerTransforms* layerTransform = GetLayerTransforms(aLayer);
|
||||
float yUniformity = -1;
|
||||
if (!layerTransform->mTransforms.IsEmpty()) {
|
||||
Point stdDev = layerTransform->GetStdDev();
|
||||
yUniformity = stdDev.y;
|
||||
}
|
||||
return yUniformity;
|
||||
}
|
||||
|
||||
bool
|
||||
FrameUniformityData::ToJS(JS::MutableHandleValue aOutValue, JSContext* aContext)
|
||||
{
|
||||
dom::FrameUniformityResults results;
|
||||
dom::Sequence<dom::FrameUniformity>& layers = results.mLayerUniformities.Construct();
|
||||
|
||||
for (auto iter = mUniformities.begin(); iter != mUniformities.end(); ++iter) {
|
||||
uintptr_t layerAddr = iter->first;
|
||||
float uniformity = iter->second;
|
||||
|
||||
layers.AppendElement();
|
||||
dom::FrameUniformity& entry = layers.LastElement();
|
||||
|
||||
entry.mLayerAddress.Construct() = layerAddr;
|
||||
entry.mFrameUniformity.Construct() = uniformity;
|
||||
}
|
||||
|
||||
return dom::ToJSValue(aContext, results, aOutValue);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- Mode: C++; tab-width: 20; 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_layers_FrameUniformityData_h_
|
||||
#define mozilla_layers_FrameUniformityData_h_
|
||||
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "nsRefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
class Layer;
|
||||
|
||||
class FrameUniformityData {
|
||||
friend struct IPC::ParamTraits<FrameUniformityData>;
|
||||
|
||||
public:
|
||||
bool ToJS(JS::MutableHandleValue aOutValue, JSContext* aContext);
|
||||
// Contains the calculated frame uniformities
|
||||
std::map<uintptr_t,float> mUniformities;
|
||||
};
|
||||
|
||||
struct LayerTransforms {
|
||||
LayerTransforms() {}
|
||||
|
||||
gfx::Point GetAverage();
|
||||
gfx::Point GetStdDev();
|
||||
|
||||
// 60 fps * 5 seconds worth of data
|
||||
nsAutoTArray<gfx::Point, 300> mTransforms;
|
||||
};
|
||||
|
||||
class LayerTransformRecorder {
|
||||
public:
|
||||
LayerTransformRecorder() {}
|
||||
~LayerTransformRecorder();
|
||||
|
||||
void RecordTransform(Layer* aLayer, const gfx::Point& aTransform);
|
||||
void Reset();
|
||||
void EndTest(FrameUniformityData* aOutData);
|
||||
|
||||
private:
|
||||
float CalculateFrameUniformity(uintptr_t aLayer);
|
||||
LayerTransforms* GetLayerTransforms(uintptr_t aLayer);
|
||||
std::map<uintptr_t,LayerTransforms*> mFrameTransforms;
|
||||
};
|
||||
|
||||
} // mozilla
|
||||
} // layers
|
||||
|
||||
namespace IPC {
|
||||
template<>
|
||||
struct ParamTraits<mozilla::layers::FrameUniformityData>
|
||||
{
|
||||
typedef mozilla::layers::FrameUniformityData paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mUniformities);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
return ParamTraitsStd<std::map<uintptr_t,float>>::Read(aMsg, aIter, &aResult->mUniformities);
|
||||
}
|
||||
};
|
||||
|
||||
}// ipc
|
||||
|
||||
#endif // mozilla_layers_FrameUniformityData_h_
|
|
@ -37,6 +37,7 @@
|
|||
#include "mozilla/layers/CompositorLRU.h" // for CompositorLRU
|
||||
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
#include "mozilla/layers/FrameUniformityData.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/layers/PLayerTransactionParent.h"
|
||||
|
@ -1324,6 +1325,13 @@ CompositorParent::ApplyAsyncProperties(LayerTransactionParent* aLayerTree)
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorParent::RecvGetFrameUniformity(FrameUniformityData* aOutData)
|
||||
{
|
||||
mCompositionManager->GetFrameUniformity(aOutData);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorParent::RecvRequestOverfill()
|
||||
{
|
||||
|
@ -1713,6 +1721,13 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual bool RecvGetFrameUniformity(FrameUniformityData* aOutData) override
|
||||
{
|
||||
// Don't support calculating frame uniformity on the child process and
|
||||
// this is just a stub for now.
|
||||
MOZ_ASSERT(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells this CompositorParent to send a message when the compositor has received the transaction.
|
||||
|
|
|
@ -229,6 +229,7 @@ public:
|
|||
base::ProcessHandle aPeerProcess,
|
||||
mozilla::ipc::ProtocolCloneContext* aCtx) override;
|
||||
|
||||
virtual bool RecvGetFrameUniformity(FrameUniformityData* aOutData) override;
|
||||
virtual bool RecvRequestOverfill() override;
|
||||
virtual bool RecvWillStop() override;
|
||||
virtual bool RecvStop() override;
|
||||
|
|
|
@ -19,6 +19,7 @@ using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
|
|||
using mozilla::CrossProcessMutexHandle from "mozilla/ipc/CrossProcessMutex.h";
|
||||
using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
|
||||
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
|
||||
using class mozilla::layers::FrameUniformityData from "mozilla/layers/FrameUniformityData.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -80,6 +81,9 @@ parent:
|
|||
// Child sends the parent a request for fill ratio numbers.
|
||||
async RequestOverfill();
|
||||
|
||||
// Child requests frame uniformity measurements
|
||||
sync GetFrameUniformity() returns (FrameUniformityData data);
|
||||
|
||||
// The child is about to be destroyed, so perform any necessary cleanup.
|
||||
sync WillStop();
|
||||
|
||||
|
|
|
@ -125,6 +125,7 @@ EXPORTS.mozilla.layers += [
|
|||
'composite/ColorLayerComposite.h',
|
||||
'composite/ContainerLayerComposite.h',
|
||||
'composite/ContentHost.h',
|
||||
'composite/FrameUniformityData.h',
|
||||
'composite/ImageHost.h',
|
||||
'composite/ImageLayerComposite.h',
|
||||
'composite/LayerManagerComposite.h',
|
||||
|
@ -277,6 +278,7 @@ UNIFIED_SOURCES += [
|
|||
'composite/ContainerLayerComposite.cpp',
|
||||
'composite/ContentHost.cpp',
|
||||
'composite/FPSCounter.cpp',
|
||||
'composite/FrameUniformityData.cpp',
|
||||
'composite/ImageHost.cpp',
|
||||
'composite/ImageLayerComposite.cpp',
|
||||
'composite/LayerManagerComposite.cpp',
|
||||
|
@ -391,6 +393,7 @@ CXXFLAGS += [
|
|||
]
|
||||
|
||||
MOCHITEST_MANIFESTS += ['apz/test/mochitest.ini']
|
||||
MOCHITEST_CHROME_MANIFESTS += ['apz/test/chrome.ini']
|
||||
|
||||
CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
|
||||
CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
|
|
|
@ -240,6 +240,7 @@ private:
|
|||
DECL_GFX_PREF(Once, "gfx.touch.resample.old-touch-threshold",TouchResampleOldTouchThreshold, int32_t, 17);
|
||||
DECL_GFX_PREF(Once, "gfx.touch.resample.vsync-adjust", TouchVsyncSampleAdjust, int32_t, 5);
|
||||
|
||||
DECL_GFX_PREF(Live, "gfx.vsync.collect-scroll-transforms", CollectScrollTransforms, bool, false);
|
||||
DECL_GFX_PREF(Once, "gfx.vsync.compositor", VsyncAlignedCompositor, bool, false);
|
||||
// On b2g, in really bad cases, I've seen up to 80 ms delays between touch events and the main thread
|
||||
// processing them. So 80 ms / 16 = 5 vsync events. Double it up just to be on the safe side, so 10.
|
||||
|
|
Загрузка…
Ссылка в новой задаче