Bug 1256408 - Add graphics microbenchmarking. r=mstange
MozReview-Commit-ID: H4IRZuLy7do
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -1,16 +1,17 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "gfxPrefs.h"
#include "gfxUtils.h"
#include "gtest/gtest.h"
+#include "gtest/MozGTestBench.h"
#include "TestLayers.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/RefPtr.h"
#include "mozilla/layers/BasicCompositor.h" // for BasicCompositor
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/LayerManagerComposite.h"
@@ -222,49 +223,56 @@ static bool CompositeAndCompare(RefPtr<L
return true;
}
TEST(Gfx, CompositorConstruct)
{
auto layerManagers = GetLayerManagers(GetPlatformBackends());
}
-TEST(Gfx, CompositorSimpleTree)
-{
+static void CompositorSimpleTree() {
+ const int benchmarkRepeatCount = 30;
+
+ RefPtr<DrawTarget> refDT = CreateDT();
+ refDT->FillRect(Rect(0, 0, gCompWidth, gCompHeight), ColorPattern(Color(1.f, 0.f, 1.f, 1.f)));
+ refDT->FillRect(Rect(0, 0, 100, 100), ColorPattern(Color(1.f, 0.f, 0.f, 1.f)));
+ refDT->FillRect(Rect(0, 50, 100, 100), ColorPattern(Color(0.f, 0.f, 1.f, 1.f)));
+
auto layerManagers = GetLayerManagers(GetPlatformBackends());
for (size_t i = 0; i < layerManagers.size(); i++) {
- RefPtr<LayerManagerComposite> layerManager = layerManagers[i].mLayerManager;
- RefPtr<LayerManager> lmBase = layerManager.get();
- nsTArray<RefPtr<Layer>> layers;
- nsIntRegion layerVisibleRegion[] = {
- nsIntRegion(IntRect(0, 0, gCompWidth, gCompHeight)),
- nsIntRegion(IntRect(0, 0, gCompWidth, gCompHeight)),
- nsIntRegion(IntRect(0, 0, 100, 100)),
- nsIntRegion(IntRect(0, 50, 100, 100)),
- };
- RefPtr<Layer> root = CreateLayerTree("c(ooo)", layerVisibleRegion, nullptr, lmBase, layers);
+ // Benchmark n composites
+ for (size_t n = 0; n < benchmarkRepeatCount; n++) {
+ RefPtr<LayerManagerComposite> layerManager = layerManagers[i].mLayerManager;
+ RefPtr<LayerManager> lmBase = layerManager.get();
+ nsTArray<RefPtr<Layer>> layers;
+ nsIntRegion layerVisibleRegion[] = {
+ nsIntRegion(IntRect(0, 0, gCompWidth, gCompHeight)),
+ nsIntRegion(IntRect(0, 0, gCompWidth, gCompHeight)),
+ nsIntRegion(IntRect(0, 0, 100, 100)),
+ nsIntRegion(IntRect(0, 50, 100, 100)),
+ };
+ RefPtr<Layer> root = CreateLayerTree("c(ooo)", layerVisibleRegion, nullptr, lmBase, layers);
- { // background
- ColorLayer* colorLayer = layers[1]->AsColorLayer();
- colorLayer->SetColor(Color(1.f, 0.f, 1.f, 1.f));
- colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
- }
+ { // background
+ ColorLayer* colorLayer = layers[1]->AsColorLayer();
+ colorLayer->SetColor(Color(1.f, 0.f, 1.f, 1.f));
+ colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
+ }
- {
- ColorLayer* colorLayer = layers[2]->AsColorLayer();
- colorLayer->SetColor(Color(1.f, 0.f, 0.f, 1.f));
- colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
- }
+ {
+ ColorLayer* colorLayer = layers[2]->AsColorLayer();
+ colorLayer->SetColor(Color(1.f, 0.f, 0.f, 1.f));
+ colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
+ }
- {
- ColorLayer* colorLayer = layers[3]->AsColorLayer();
- colorLayer->SetColor(Color(0.f, 0.f, 1.f, 1.f));
- colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
- }
+ {
+ ColorLayer* colorLayer = layers[3]->AsColorLayer();
+ colorLayer->SetColor(Color(0.f, 0.f, 1.f, 1.f));
+ colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
+ }
- RefPtr<DrawTarget> refDT = CreateDT();
- refDT->FillRect(Rect(0, 0, gCompWidth, gCompHeight), ColorPattern(Color(1.f, 0.f, 1.f, 1.f)));
- refDT->FillRect(Rect(0, 0, 100, 100), ColorPattern(Color(1.f, 0.f, 0.f, 1.f)));
- refDT->FillRect(Rect(0, 50, 100, 100), ColorPattern(Color(0.f, 0.f, 1.f, 1.f)));
- EXPECT_TRUE(CompositeAndCompare(layerManager, refDT));
+ EXPECT_TRUE(CompositeAndCompare(layerManager, refDT));
+ }
}
-}
+};
+MOZ_GTEST_BENCH(GfxBench, CompositorSimpleTree, &CompositorSimpleTree);
+
--- a/gfx/tests/gtest/TestRegion.cpp
+++ b/gfx/tests/gtest/TestRegion.cpp
@@ -1,16 +1,18 @@
/* -*- 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/. */
#include <algorithm>
#include "gtest/gtest.h"
+#include "gtest/MozGTestBench.h"
+#include "nsRect.h"
#include "nsRegion.h"
using namespace std;
class TestLargestRegion {
public:
static void TestSingleRect(nsRect r) {
nsRegion region(r);
@@ -557,8 +559,27 @@ TEST(Gfx, RegionVisitEdges) {
r.Or(r, nsRect(25, 50, 28, 5));
r.Or(r, nsRect(115, 50, 99, 5));
r.Or(r, nsRect(115, 55, 99, 12));
TestVisit(r);
}
}
+
+MOZ_GTEST_BENCH(GfxBench, RegionOr, []{
+ const int size = 5000;
+ nsRegion r;
+ for (int i = 0; i < size; i++) {
+ r = r.Or(r, nsRect(i, i, i + 10, i + 10));
+ }
+});
+
+MOZ_GTEST_BENCH(GfxBench, RegionAnd, []{
+ const int size = 5000;
+ nsRegion r(nsRect(0, 0, size, size));
+ for (int i = 0; i < size; i++) {
+ nsRegion rMissingPixel(nsRect(0, 0, size, size));
+ rMissingPixel = rMissingPixel.Sub(rMissingPixel, nsRect(i, i, 1, 1));
+ r = r.And(r, rMissingPixel);
+ }
+});
+
--- a/testing/gtest/moz.build
+++ b/testing/gtest/moz.build
@@ -15,16 +15,17 @@ if CONFIG['ENABLE_TESTS']:
'gtest/include/gtest/gtest-param-test.h',
'gtest/include/gtest/gtest-printers.h',
'gtest/include/gtest/gtest-spi.h',
'gtest/include/gtest/gtest-test-part.h',
'gtest/include/gtest/gtest-typed-test.h',
'gtest/include/gtest/gtest.h',
'gtest/include/gtest/gtest_pred_impl.h',
'gtest/include/gtest/gtest_prod.h',
+ 'mozilla/MozGTestBench.h',
]
# GTest internal are exposed in gtest.h. See comment in gtest.h
EXPORTS.gtest.internal += [
'gtest/include/gtest/internal/gtest-death-test-internal.h',
'gtest/include/gtest/internal/gtest-filepath.h',
'gtest/include/gtest/internal/gtest-internal.h',
'gtest/include/gtest/internal/gtest-linked_ptr.h',
@@ -55,16 +56,17 @@ if CONFIG['ENABLE_TESTS']:
'gmock/include/gmock/internal/gmock-internal-utils.h',
'gmock/include/gmock/internal/gmock-port.h',
]
SOURCES += [
'gmock/src/gmock-all.cc',
'gtest/src/gtest-all.cc',
'mozilla/GTestRunner.cpp',
+ 'mozilla/MozGTestBench.cpp',
]
Library('gtest')
SOURCES += [
'mozilla/SanityTest.cpp',
]
new file mode 100644
--- /dev/null
+++ b/testing/gtest/mozilla/MozGTestBench.cpp
@@ -0,0 +1,39 @@
+/* -*- 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/. */
+
+#include "MozGTestBench.h"
+#include "mozilla/TimeStamp.h"
+#include <stdio.h>
+
+#define MOZ_GTEST_BENCH_FRAMEWORK "platform_microbench"
+
+using mozilla::TimeStamp;
+
+namespace mozilla {
+void GTestBench(const char* aSuite, const char* aName,
+ const mozilla::function<void()>& aTest)
+{
+#ifdef DEBUG
+ // Run the test to make sure that it doesn't fail but don't log
+ // any measurements since it's not an optimized build.
+ aTest();
+#else
+ mozilla::TimeStamp start = TimeStamp::Now();
+
+ aTest();
+
+ int msDuration = (TimeStamp::Now() - start).ToMicroseconds();
+
+ // Print the result for each test. Let perfherder aggregate for us
+ printf("PERFHERDER_DATA: {\"framework\": {\"name\": \"%s\"}, "
+ "\"suites\": [{\"name\": \"%s\", \"subtests\": "
+ "[{\"name\": \"%s\", \"value\": %i, \"lowerIsBetter\": true}]"
+ "}]}\n",
+ MOZ_GTEST_BENCH_FRAMEWORK, aSuite, aName, msDuration);
+#endif
+}
+
+} // mozilla
+
new file mode 100644
--- /dev/null
+++ b/testing/gtest/mozilla/MozGTestBench.h
@@ -0,0 +1,22 @@
+/* -*- 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 GTEST_MOZGTESTBENCH_H
+#define GTEST_MOZGTESTBENCH_H
+
+#include "mozilla/Function.h"
+
+namespace mozilla {
+
+void GTestBench(const char* aSuite, const char* aName, const mozilla::function<void()>& aTest);
+
+} //mozilla
+
+#define MOZ_GTEST_BENCH(suite, test, lambdaOrFunc) \
+TEST(suite, test) { \
+ mozilla::GTestBench(#suite, #test, lambdaOrFunc); \
+}
+
+#endif // GTEST_MOZGTESTBENCH_H