| // Copyright 2023 The Dawn & Tint Authors |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // 1. Redistributions of source code must retain the above copyright notice, this |
| // list of conditions and the following disclaimer. |
| // |
| // 2. Redistributions in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // 3. Neither the name of the copyright holder nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #include <memory> |
| |
| #include "dawn/platform/metrics/HistogramMacros.h" |
| #include "dawn/tests/DawnTest.h" |
| #include "partition_alloc/pointers/raw_ptr.h" |
| |
| namespace dawn { |
| namespace { |
| |
| using ::testing::_; |
| using ::testing::InSequence; |
| using ::testing::NiceMock; |
| |
| class DawnHistogramMockPlatform : public dawn::platform::Platform { |
| public: |
| void SetTime(double time) { mTime = time; } |
| |
| double MonotonicallyIncreasingTime() override { return mTime; } |
| |
| MOCK_METHOD(void, |
| HistogramCustomCounts, |
| (const char* name, int sample, int min, int max, int bucketCount), |
| (override)); |
| |
| MOCK_METHOD(void, |
| HistogramCustomCountsHPC, |
| (const char* name, int sample, int min, int max, int bucketCount), |
| (override)); |
| |
| MOCK_METHOD(void, |
| HistogramEnumeration, |
| (const char* name, int sample, int boundaryValue), |
| (override)); |
| |
| MOCK_METHOD(void, HistogramSparse, (const char* name, int sample), (override)); |
| |
| MOCK_METHOD(void, HistogramBoolean, (const char* name, bool sample), (override)); |
| |
| private: |
| double mTime = 0.0; |
| }; |
| |
| class HistogramTests : public DawnTest { |
| protected: |
| void SetUp() override { DawnTest::SetUp(); } |
| |
| std::unique_ptr<platform::Platform> CreateTestPlatform() override { |
| auto p = std::make_unique<NiceMock<DawnHistogramMockPlatform>>(); |
| mMockPlatform = p.get(); |
| return p; |
| } |
| |
| raw_ptr<NiceMock<DawnHistogramMockPlatform>> mMockPlatform; |
| }; |
| |
| TEST_P(HistogramTests, Times) { |
| InSequence seq; |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("times", 1, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("medium_times", 2, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("long_times", 3, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("long_times_100", 4, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("custom_times", 5, 0, 10, 42)); |
| EXPECT_CALL(*mMockPlatform, |
| HistogramCustomCountsHPC("custom_microsecond_times", 6, 0, 100, 420)); |
| |
| DAWN_HISTOGRAM_TIMES(mMockPlatform, "times", 1); |
| DAWN_HISTOGRAM_MEDIUM_TIMES(mMockPlatform, "medium_times", 2); |
| DAWN_HISTOGRAM_LONG_TIMES(mMockPlatform, "long_times", 3); |
| DAWN_HISTOGRAM_LONG_TIMES_100(mMockPlatform, "long_times_100", 4); |
| DAWN_HISTOGRAM_CUSTOM_TIMES(mMockPlatform, "custom_times", 5, 0, 10, 42); |
| DAWN_HISTOGRAM_CUSTOM_MICROSECOND_TIMES(mMockPlatform, "custom_microsecond_times", 6, 0, 100, |
| 420); |
| } |
| |
| TEST_P(HistogramTests, Percentage) { |
| InSequence seq; |
| EXPECT_CALL(*mMockPlatform, HistogramEnumeration("percentage", 0, 101)); |
| EXPECT_CALL(*mMockPlatform, HistogramEnumeration("percentage", 42, 101)); |
| EXPECT_CALL(*mMockPlatform, HistogramEnumeration("percentage", 100, 101)); |
| |
| DAWN_HISTOGRAM_PERCENTAGE(mMockPlatform, "percentage", 0); |
| DAWN_HISTOGRAM_PERCENTAGE(mMockPlatform, "percentage", 42); |
| DAWN_HISTOGRAM_PERCENTAGE(mMockPlatform, "percentage", 100); |
| } |
| |
| TEST_P(HistogramTests, Boolean) { |
| InSequence seq; |
| EXPECT_CALL(*mMockPlatform, HistogramBoolean("boolean", false)); |
| EXPECT_CALL(*mMockPlatform, HistogramBoolean("boolean", true)); |
| |
| DAWN_HISTOGRAM_BOOLEAN(mMockPlatform, "boolean", false); |
| DAWN_HISTOGRAM_BOOLEAN(mMockPlatform, "boolean", true); |
| } |
| |
| TEST_P(HistogramTests, Enumeration) { |
| enum Animal { Dog, Cat, Bear, Count }; |
| |
| InSequence seq; |
| EXPECT_CALL(*mMockPlatform, HistogramEnumeration("animal", Animal::Dog, Animal::Count)); |
| EXPECT_CALL(*mMockPlatform, HistogramEnumeration("animal", Animal::Cat, Animal::Count)); |
| EXPECT_CALL(*mMockPlatform, HistogramEnumeration("animal", Animal::Bear, Animal::Count)); |
| |
| DAWN_HISTOGRAM_ENUMERATION(mMockPlatform, "animal", Animal::Dog, Animal::Count); |
| DAWN_HISTOGRAM_ENUMERATION(mMockPlatform, "animal", Animal::Cat, Animal::Count); |
| DAWN_HISTOGRAM_ENUMERATION(mMockPlatform, "animal", Animal::Bear, Animal::Count); |
| } |
| |
| TEST_P(HistogramTests, Memory) { |
| InSequence seq; |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("kb", 1, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("mb", 2, _, _, _)); |
| |
| DAWN_HISTOGRAM_MEMORY_KB(mMockPlatform, "kb", 1); |
| DAWN_HISTOGRAM_MEMORY_MB(mMockPlatform, "mb", 2); |
| } |
| |
| TEST_P(HistogramTests, Sparse) { |
| InSequence seq; |
| EXPECT_CALL(*mMockPlatform, HistogramSparse("sparse", 1)); |
| EXPECT_CALL(*mMockPlatform, HistogramSparse("sparse", 2)); |
| |
| DAWN_HISTOGRAM_SPARSE(mMockPlatform, "sparse", 1); |
| DAWN_HISTOGRAM_SPARSE(mMockPlatform, "sparse", 2); |
| } |
| |
| TEST_P(HistogramTests, ScopedTimer) { |
| InSequence seq; |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("timer0", 2'500, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("timer1", 15'500, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("timer4", 2'500, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCounts("timer3", 6'000, _, _, _)); |
| EXPECT_CALL(*mMockPlatform, HistogramCustomCountsHPC("timer5", 1'500'000, _, _, _)); |
| |
| { |
| mMockPlatform->SetTime(1.0); |
| SCOPED_DAWN_HISTOGRAM_TIMER(mMockPlatform, "timer0"); |
| mMockPlatform->SetTime(3.5); |
| } |
| { |
| mMockPlatform->SetTime(10.0); |
| SCOPED_DAWN_HISTOGRAM_LONG_TIMER(mMockPlatform, "timer1"); |
| mMockPlatform->SetTime(25.5); |
| } |
| { |
| mMockPlatform->SetTime(1.0); |
| SCOPED_DAWN_HISTOGRAM_TIMER(mMockPlatform, "timer3"); |
| mMockPlatform->SetTime(4.5); |
| SCOPED_DAWN_HISTOGRAM_LONG_TIMER(mMockPlatform, "timer4"); |
| mMockPlatform->SetTime(7.0); |
| } |
| { |
| mMockPlatform->SetTime(1.0); |
| SCOPED_DAWN_HISTOGRAM_TIMER_MICROS(mMockPlatform, "timer5"); |
| mMockPlatform->SetTime(2.5); |
| } |
| } |
| |
| DAWN_INSTANTIATE_TEST(HistogramTests, |
| D3D11Backend(), |
| D3D12Backend(), |
| MetalBackend(), |
| NullBackend(), |
| OpenGLBackend(), |
| OpenGLESBackend(), |
| VulkanBackend()); |
| |
| } // namespace |
| } // namespace dawn |