tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestDecodersPerf.cpp (6389B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "gtest/gtest.h"
      6 #include "gtest/MozGTestBench.h"
      7 
      8 #include "Common.h"
      9 #include "Decoder.h"
     10 #include "DecoderFactory.h"
     11 #include "IDecodingTask.h"
     12 #include "mozilla/RefPtr.h"
     13 #include "ProgressTracker.h"
     14 #include "SourceBuffer.h"
     15 
     16 using namespace mozilla;
     17 using namespace mozilla::gfx;
     18 using namespace mozilla::image;
     19 
     20 namespace {
     21 
     22 static void CheckDecoderState(const ImageTestCase& aTestCase,
     23                              image::Decoder* aDecoder,
     24                              const IntSize& aOutputSize) {
     25  // image::Decoder should match what we asked for in the MIME type.
     26  EXPECT_NE(aDecoder->GetType(), DecoderType::UNKNOWN);
     27  EXPECT_EQ(aDecoder->GetType(),
     28            DecoderFactory::GetDecoderType(aTestCase.mMimeType));
     29 
     30  EXPECT_TRUE(aDecoder->GetDecodeDone());
     31  EXPECT_FALSE(aDecoder->HasError());
     32 
     33  // Verify that the decoder made the expected progress.
     34  Progress progress = aDecoder->TakeProgress();
     35  EXPECT_FALSE(bool(progress & FLAG_HAS_ERROR));
     36  EXPECT_FALSE(bool(aTestCase.mFlags & TEST_CASE_HAS_ERROR));
     37 
     38  EXPECT_TRUE(bool(progress & FLAG_SIZE_AVAILABLE));
     39  EXPECT_TRUE(bool(progress & FLAG_DECODE_COMPLETE));
     40  EXPECT_TRUE(bool(progress & FLAG_FRAME_COMPLETE));
     41  EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT),
     42            bool(progress & FLAG_HAS_TRANSPARENCY));
     43  EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED),
     44            bool(progress & FLAG_IS_ANIMATED));
     45 
     46  // The decoder should get the correct size.
     47  OrientedIntSize size = aDecoder->Size();
     48  EXPECT_EQ(aTestCase.mSize.width, size.width);
     49  EXPECT_EQ(aTestCase.mSize.height, size.height);
     50 
     51  // Get the current frame, which is always the first frame of the image
     52  // because CreateAnonymousDecoder() forces a first-frame-only decode.
     53  RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
     54  RefPtr<SourceSurface> surface = currentFrame->GetSourceSurface();
     55 
     56  // Verify that the resulting surfaces matches our expectations.
     57  EXPECT_TRUE(surface->IsDataSourceSurface());
     58  EXPECT_TRUE(surface->GetFormat() == SurfaceFormat::OS_RGBX ||
     59              surface->GetFormat() == SurfaceFormat::OS_RGBA);
     60  EXPECT_EQ(aOutputSize, surface->GetSize());
     61 }
     62 
     63 template <typename Func>
     64 static void WithSingleChunkDecode(const ImageTestCase& aTestCase,
     65                                  SourceBuffer* aSourceBuffer,
     66                                  const Maybe<IntSize>& aOutputSize,
     67                                  Func aResultChecker) {
     68  auto sourceBuffer = WrapNotNull(RefPtr<SourceBuffer>(aSourceBuffer));
     69 
     70  // Create a decoder.
     71  DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType);
     72  RefPtr<image::Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(
     73      decoderType, sourceBuffer, aOutputSize, DecoderFlags::FIRST_FRAME_ONLY,
     74      aTestCase.mSurfaceFlags);
     75  ASSERT_TRUE(decoder != nullptr);
     76  RefPtr<IDecodingTask> task =
     77      new AnonymousDecodingTask(WrapNotNull(decoder), /* aResumable */ false);
     78 
     79  // Run the full decoder synchronously.
     80  task->Run();
     81 
     82  // Call the lambda to verify the expected results.
     83  aResultChecker(decoder);
     84 }
     85 
     86 static void CheckDecode(const ImageTestCase& aTestCase,
     87                        SourceBuffer* aSourceBuffer) {
     88  WithSingleChunkDecode(
     89      aTestCase, aSourceBuffer, Nothing(), [&](image::Decoder* aDecoder) {
     90        CheckDecoderState(aTestCase, aDecoder, aTestCase.mSize);
     91      });
     92 }
     93 
     94 static void CheckDownscaleDuringDecode(const ImageTestCase& aTestCase,
     95                                       SourceBuffer* aSourceBuffer) {
     96  IntSize outputSize(20, 20);
     97  WithSingleChunkDecode(aTestCase, aSourceBuffer, Some(outputSize),
     98                        [&](image::Decoder* aDecoder) {
     99                          CheckDecoderState(aTestCase, aDecoder, outputSize);
    100                        });
    101 }
    102 
    103 #define IMAGE_GTEST_BENCH_FIXTURE(test_fixture, test_case) \
    104  class test_fixture : public ImageBenchmarkBase {         \
    105   protected:                                              \
    106    test_fixture() : ImageBenchmarkBase(test_case()) {}    \
    107  };
    108 
    109 #define IMAGE_GTEST_NATIVE_BENCH_F(test_fixture) \
    110  MOZ_GTEST_BENCH_F(test_fixture, Native,        \
    111                    [this] { CheckDecode(mTestCase, mSourceBuffer); });
    112 
    113 #define IMAGE_GTEST_DOWNSCALE_BENCH_F(test_fixture)       \
    114  MOZ_GTEST_BENCH_F(test_fixture, Downscale, [this] {     \
    115    CheckDownscaleDuringDecode(mTestCase, mSourceBuffer); \
    116  });
    117 
    118 #define IMAGE_GTEST_NO_COLOR_MANAGEMENT_BENCH_F(test_fixture)         \
    119  MOZ_GTEST_BENCH_F(test_fixture, NoColorManagement, [this] {         \
    120    ImageTestCase testCase = mTestCase;                               \
    121    testCase.mSurfaceFlags |= SurfaceFlags::NO_COLORSPACE_CONVERSION; \
    122    CheckDecode(testCase, mSourceBuffer);                             \
    123  });
    124 
    125 #define IMAGE_GTEST_NO_PREMULTIPLY_BENCH_F(test_fixture)          \
    126  MOZ_GTEST_BENCH_F(test_fixture, NoPremultiplyAlpha, [this] {    \
    127    ImageTestCase testCase = mTestCase;                           \
    128    testCase.mSurfaceFlags |= SurfaceFlags::NO_PREMULTIPLY_ALPHA; \
    129    CheckDecode(testCase, mSourceBuffer);                         \
    130  });
    131 
    132 #define IMAGE_GTEST_BENCH_F(type, test)                            \
    133  IMAGE_GTEST_BENCH_FIXTURE(ImageDecodersPerf_##type##_##test,     \
    134                            Perf##test##type##TestCase)            \
    135  IMAGE_GTEST_NATIVE_BENCH_F(ImageDecodersPerf_##type##_##test)    \
    136  IMAGE_GTEST_DOWNSCALE_BENCH_F(ImageDecodersPerf_##type##_##test) \
    137  IMAGE_GTEST_NO_COLOR_MANAGEMENT_BENCH_F(ImageDecodersPerf_##type##_##test)
    138 
    139 #define IMAGE_GTEST_BENCH_ALPHA_F(type, test) \
    140  IMAGE_GTEST_BENCH_F(type, test)             \
    141  IMAGE_GTEST_NO_PREMULTIPLY_BENCH_F(ImageDecodersPerf_##type##_##test)
    142 
    143 IMAGE_GTEST_BENCH_F(JPG, YCbCr)
    144 IMAGE_GTEST_BENCH_F(JPG, Cmyk)
    145 IMAGE_GTEST_BENCH_F(JPG, Gray)
    146 
    147 IMAGE_GTEST_BENCH_F(PNG, Rgb)
    148 IMAGE_GTEST_BENCH_F(PNG, Gray)
    149 IMAGE_GTEST_BENCH_ALPHA_F(PNG, RgbAlpha)
    150 IMAGE_GTEST_BENCH_ALPHA_F(PNG, GrayAlpha)
    151 
    152 IMAGE_GTEST_BENCH_F(WebP, RgbLossless)
    153 IMAGE_GTEST_BENCH_F(WebP, RgbLossy)
    154 IMAGE_GTEST_BENCH_ALPHA_F(WebP, RgbAlphaLossless)
    155 IMAGE_GTEST_BENCH_ALPHA_F(WebP, RgbAlphaLossy)
    156 
    157 IMAGE_GTEST_BENCH_F(GIF, Rgb)
    158 
    159 }  // namespace