Skip to content

Commit

Permalink
Cache and load skia animations via resource bundle
Browse files Browse the repository at this point in the history
This patch implements the ability to load skia vector animation files
via the resource bundle. Each file is only loaded once and cached for
future use. ResourceBundle expects the animation file to be gzipped.

UMA metrics are also recorded to note the time to uncompress and parse
each animation file.

Bug: 890512
Change-Id: Ie0e17dbee9198b12a886f3739a034ad366bf9478
Component: ResourceBundle, skia vector animations
Reviewed-on: https://chromium-review.googlesource.com/c/1272800
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Steven Holte <holte@chromium.org>
Commit-Queue: Malay Keshav <malaykeshav@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601385}
  • Loading branch information
Malay Keshav authored and Commit Bot committed Oct 20, 2018
1 parent 831694a commit 9d39d8b
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 0 deletions.
7 changes: 7 additions & 0 deletions tools/metrics/histograms/histograms.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112847,6 +112847,13 @@ uploading your change for review.
</summary>
</histogram>

<histogram name="UncompressAndParseSkiaVectorAsset" units="microseconds">
<owner>malaykeshav@chromium.org</owner>
<summary>
Records the time spent in uncompressing a gzipped animation file.
</summary>
</histogram>

<histogram name="UnifiedConsent.ConsentBump.Action"
enum="UnifiedConsentBumpAction" expires_after="2019-08-01">
<owner>tangltom@chromium.org</owner>
Expand Down
15 changes: 15 additions & 0 deletions ui/aura_extra/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,18 @@ component("aura_extra") {
"//ui/gfx/geometry",
]
}

source_set("vector_resource") {
sources = [
"skia_vector_resource.cc",
"skia_vector_resource.h",
]

deps = [
"//base",
"//cc/paint",
"//third_party/zlib/google:compression_utils",
"//ui/base",
"//ui/display",
]
}
3 changes: 3 additions & 0 deletions ui/aura_extra/DEPS
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
include_rules = [
"+cc/paint",
"+third_party/skia",
"+third_party/zlib/google/compression_utils.h",
"+ui/aura",
"+ui/base",
"+ui/compositor",
"+ui/display",
"+ui/events",
"+ui/gfx",
"+ui/platform_window",
Expand Down
83 changes: 83 additions & 0 deletions ui/aura_extra/skia_vector_resource.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/aura_extra/skia_vector_resource.h"

#include <map>

#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/paint/skottie_wrapper.h"
#include "third_party/zlib/google/compression_utils.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/skia_vector_animation.h"

#if defined(OS_WIN)
#include "ui/display/win/dpi.h"
#endif

namespace aura_extra {
namespace {

// Cached vector graphics. Each resource is loaded and unzipped only once.
// TODO(malaykeshav): Investigate if this needs to be an MRU cache with a size
// limit as the usage increases.
using VectorAssetCache = std::map<int, scoped_refptr<cc::SkottieWrapper>>;
VectorAssetCache& GetVectorAssetCache() {
static base::NoDestructor<VectorAssetCache> vector_graphic_cache;
return *vector_graphic_cache;
}

} // namespace

std::unique_ptr<gfx::SkiaVectorAnimation> GetVectorAnimationNamed(
int resource_id) {
auto found = GetVectorAssetCache().find(resource_id);
if (found != GetVectorAssetCache().end())
return std::make_unique<gfx::SkiaVectorAnimation>(found->second);

auto& rb = ui::ResourceBundle::GetSharedInstance();
#if defined(OS_CHROMEOS)
ui::ScaleFactor scale_factor_to_load = rb.GetMaxScaleFactor();
#elif defined(OS_WIN)
ui::ScaleFactor scale_factor_to_load = display::win::GetDPIScale() > 1.25
? rb.GetMaxScaleFactor()
: ui::SCALE_FACTOR_100P;
#else
ui::ScaleFactor scale_factor_to_load = ui::SCALE_FACTOR_100P;
#endif
// Clamp the scale factor to 2x. At most we will only be needing 2 versions
// for a given file.
if (scale_factor_to_load > ui::SCALE_FACTOR_200P)
scale_factor_to_load = ui::SCALE_FACTOR_200P;

auto compressed_raw_data =
rb.GetRawDataResourceForScale(resource_id, scale_factor_to_load);
auto* uncompressed_bytes = new base::RefCountedBytes(
compression::GetUncompressedSize(compressed_raw_data));
base::StringPiece uncompressed_str_piece(
reinterpret_cast<const char*>(uncompressed_bytes->front()),
uncompressed_bytes->size());

TRACE_EVENT1("ui", "GetVectorAnimationNamed uncompress and parse",
"zip size bytes", uncompressed_bytes->size());
base::TimeTicks start_timestamp = base::TimeTicks::Now();
CHECK(
compression::GzipUncompress(compressed_raw_data, uncompressed_str_piece));

auto skottie = base::MakeRefCounted<cc::SkottieWrapper>(uncompressed_bytes);

UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
"UncompressAndParseSkiaVectorAsset",
base::TimeTicks::Now() - start_timestamp,
base::TimeDelta::FromMicroseconds(1),
base::TimeDelta::FromMilliseconds(50), 100);
auto inserted = GetVectorAssetCache().emplace(resource_id, skottie);
DCHECK(inserted.second);
return std::make_unique<gfx::SkiaVectorAnimation>(inserted.first->second);
}

} // namespace aura_extra
24 changes: 24 additions & 0 deletions ui/aura_extra/skia_vector_resource.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_AURA_EXTRA_SKIA_VECTOR_RESOURCE_H_
#define UI_AURA_EXTRA_SKIA_VECTOR_RESOURCE_H_

#include <memory>

namespace gfx {
class SkiaVectorAnimation;
} // namespace gfx

namespace aura_extra {

// Gets a vector graphic resource specified by |resource_id| from the current
// module data and returns it as a SkiaVectorAnimation object. This expects the
// resource to be gzipped.
std::unique_ptr<gfx::SkiaVectorAnimation> GetVectorAnimationNamed(
int resource_id);

} // namespace aura_extra

#endif // UI_AURA_EXTRA_SKIA_VECTOR_RESOURCE_H_

0 comments on commit 9d39d8b

Please sign in to comment.