| // Copyright 2017 The Chromium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "cc/tiles/gpu_image_decode_cache.h" | 
 |  | 
 | #include <memory> | 
 | #include <vector> | 
 |  | 
 | #include "base/timer/lap_timer.h" | 
 | #include "cc/paint/draw_image.h" | 
 | #include "cc/paint/paint_image_builder.h" | 
 | #include "cc/raster/tile_task.h" | 
 | #include "components/viz/test/test_in_process_context_provider.h" | 
 | #include "gpu/command_buffer/client/raster_interface.h" | 
 | #include "testing/gtest/include/gtest/gtest.h" | 
 | #include "testing/perf/perf_result_reporter.h" | 
 | #include "third_party/skia/include/core/SkAlphaType.h" | 
 | #include "third_party/skia/include/core/SkBitmap.h" | 
 | #include "third_party/skia/include/core/SkImage.h" | 
 | #include "third_party/skia/include/core/SkImageInfo.h" | 
 | #include "third_party/skia/include/core/SkM44.h" | 
 | #include "third_party/skia/include/core/SkSize.h" | 
 | #include "third_party/skia/include/gpu/GpuTypes.h" | 
 |  | 
 | namespace cc { | 
 | namespace { | 
 |  | 
 | static const int kTimeLimitMillis = 2000; | 
 | static const int kWarmupRuns = 5; | 
 | static const int kTimeCheckInterval = 10; | 
 | static const int kCacheSize = 128 * 1024 * 1024; | 
 |  | 
 | sk_sp<SkImage> CreateImage(int width, int height) { | 
 |   SkBitmap bitmap; | 
 |   bitmap.allocPixels(SkImageInfo::MakeS32(width, height, kPremul_SkAlphaType)); | 
 |   return SkImages::RasterFromBitmap(bitmap); | 
 | } | 
 |  | 
 | SkM44 CreateMatrix(const SkSize& scale) { | 
 |   return SkM44::Scale(scale.width(), scale.height()); | 
 | } | 
 |  | 
 | class GpuImageDecodeCachePerfTest : public testing::Test { | 
 |  public: | 
 |   GpuImageDecodeCachePerfTest() | 
 |       : timer_(kWarmupRuns, | 
 |                base::Milliseconds(kTimeLimitMillis), | 
 |                kTimeCheckInterval), | 
 |         context_provider_( | 
 |             base::MakeRefCounted<viz::TestInProcessContextProvider>( | 
 |                 viz::TestContextType::kGpuRaster, | 
 |                 /*support_locking=*/false)) {} | 
 |  | 
 |   void SetUp() override { | 
 |     gpu::ContextResult result = context_provider_->BindToCurrentSequence(); | 
 |     max_texture_size_ = | 
 |         context_provider_->ContextCapabilities().max_texture_size; | 
 |     ASSERT_EQ(result, gpu::ContextResult::kSuccess); | 
 |     cache_ = std::make_unique<GpuImageDecodeCache>( | 
 |         context_provider_.get(), kRGBA_8888_SkColorType, kCacheSize, | 
 |         MaxTextureSize(), nullptr); | 
 |   } | 
 |  | 
 |  protected: | 
 |   size_t MaxTextureSize() const { return 4096; } | 
 |  | 
 |   // Returns dimensions for an image that will fit in GPU memory. | 
 |   gfx::Size GetNormalImageSize() const { | 
 |     int dimension = std::min(100, max_texture_size_ - 1); | 
 |     return gfx::Size(dimension, dimension); | 
 |   } | 
 |  | 
 |   perf_test::PerfResultReporter SetUpReporter( | 
 |       const std::string& metric_suffix) { | 
 |     perf_test::PerfResultReporter reporter("gpu_image_decode_cache", "GPU"); | 
 |     reporter.RegisterImportantMetric(metric_suffix, "runs/s"); | 
 |     return reporter; | 
 |   } | 
 |  | 
 |   base::LapTimer timer_; | 
 |   scoped_refptr<viz::TestInProcessContextProvider> context_provider_; | 
 |   std::unique_ptr<GpuImageDecodeCache> cache_; | 
 |   int max_texture_size_ = 0; | 
 | }; | 
 |  | 
 | TEST_F(GpuImageDecodeCachePerfTest, DecodeWithColorConversion) { | 
 |   timer_.Reset(); | 
 |   auto gfx_size = GetNormalImageSize(); | 
 |   do { | 
 |     DrawImage image( | 
 |         PaintImageBuilder::WithDefault() | 
 |             .set_id(PaintImage::GetNextId()) | 
 |             .set_image(CreateImage(gfx_size.width(), gfx_size.height()), | 
 |                        PaintImage::GetNextContentId()) | 
 |             .TakePaintImage(), | 
 |         false, SkIRect::MakeWH(gfx_size.width(), gfx_size.height()), | 
 |         PaintFlags::FilterQuality::kMedium, | 
 |         CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u, | 
 |         TargetColorParams(gfx::ColorSpace::CreateXYZD50())); | 
 |  | 
 |     DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image); | 
 |     cache_->DrawWithImageFinished(image, decoded_image); | 
 |     timer_.NextLap(); | 
 |   } while (!timer_.HasTimeLimitExpired()); | 
 |  | 
 |   perf_test::PerfResultReporter reporter = | 
 |       SetUpReporter("_with_color_conversion"); | 
 |   reporter.AddResult("_with_color_conversion", timer_.LapsPerSecond()); | 
 | } | 
 |  | 
 | TEST_F(GpuImageDecodeCachePerfTest, DecodeWithMips) { | 
 |   auto gfx_size = GetNormalImageSize(); | 
 |   timer_.Reset(); | 
 |   do { | 
 |     DrawImage image( | 
 |         PaintImageBuilder::WithDefault() | 
 |             .set_id(PaintImage::GetNextId()) | 
 |             .set_image(CreateImage(gfx_size.width(), gfx_size.height()), | 
 |                        PaintImage::GetNextContentId()) | 
 |             .TakePaintImage(), | 
 |         false, SkIRect::MakeWH(gfx_size.width(), gfx_size.height()), | 
 |         PaintFlags::FilterQuality::kMedium, | 
 |         CreateMatrix(SkSize::Make(0.6f, 0.6f)), 0u, TargetColorParams()); | 
 |  | 
 |     DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image); | 
 |  | 
 |     cache_->DrawWithImageFinished(image, decoded_image); | 
 |     timer_.NextLap(); | 
 |   } while (!timer_.HasTimeLimitExpired()); | 
 |  | 
 |   perf_test::PerfResultReporter reporter = SetUpReporter("_with_mips"); | 
 |   reporter.AddResult("_with_mips", timer_.LapsPerSecond()); | 
 | } | 
 |  | 
 | TEST_F(GpuImageDecodeCachePerfTest, AcquireExistingImages) { | 
 |   timer_.Reset(); | 
 |   auto gfx_size = GetNormalImageSize(); | 
 |   DrawImage image( | 
 |       PaintImageBuilder::WithDefault() | 
 |           .set_id(PaintImage::GetNextId()) | 
 |           .set_image(CreateImage(gfx_size.width(), gfx_size.height()), | 
 |                      PaintImage::GetNextContentId()) | 
 |           .TakePaintImage(), | 
 |       false, SkIRect::MakeWH(gfx_size.width(), gfx_size.height()), | 
 |       PaintFlags::FilterQuality::kMedium, | 
 |       CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u, | 
 |       TargetColorParams(gfx::ColorSpace::CreateXYZD50())); | 
 |  | 
 |   DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image); | 
 |   cache_->DrawWithImageFinished(image, decoded_image); | 
 |  | 
 |   do { | 
 |     decoded_image = cache_->GetDecodedImageForDraw(image); | 
 |     cache_->DrawWithImageFinished(image, decoded_image); | 
 |     timer_.NextLap(); | 
 |   } while (!timer_.HasTimeLimitExpired()); | 
 |  | 
 |   perf_test::PerfResultReporter reporter = | 
 |       SetUpReporter("_acquire_existing_images"); | 
 |   reporter.AddResult("_acquire_existing_images", timer_.LapsPerSecond()); | 
 | } | 
 |  | 
 | }  // namespace | 
 | }  // namespace cc |