ambient_animation_static_resources_impl.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/ambient/resources/ambient_animation_static_resources.h"
  5. #include <cstdint>
  6. #include <utility>
  7. #include <vector>
  8. #include "ash/ambient/resources/ambient_animation_resource_constants.h"
  9. #include "ash/ambient/resources/grit/ash_ambient_lottie_resources.h"
  10. #include "base/check.h"
  11. #include "base/containers/span.h"
  12. #include "base/logging.h"
  13. #include "cc/paint/skottie_wrapper.h"
  14. #include "ui/base/resource/resource_bundle.h"
  15. #include "ui/gfx/image/image_skia.h"
  16. namespace ash {
  17. namespace {
  18. using AnimationThemeToResourceIdMap =
  19. base::flat_map<AmbientAnimationTheme, int>;
  20. using AssetIdToResourceIdMap = base::flat_map<base::StringPiece, int>;
  21. const AnimationThemeToResourceIdMap& GetAnimationThemeToLottieResourceIdMap() {
  22. static const AnimationThemeToResourceIdMap* m =
  23. new AnimationThemeToResourceIdMap(
  24. {{AmbientAnimationTheme::kFeelTheBreeze,
  25. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_ANIMATION_JSON},
  26. {AmbientAnimationTheme::kFloatOnBy,
  27. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_ANIMATION_JSON}});
  28. return *m;
  29. }
  30. // TODO(esum): Look into auto-generating this map and the one above via a
  31. // build-time script.
  32. AssetIdToResourceIdMap GetAssetIdToResourceIdMapForTheme(
  33. AmbientAnimationTheme theme) {
  34. base::flat_map<AmbientAnimationTheme, AssetIdToResourceIdMap> m = {
  35. // Themes
  36. {
  37. // Theme: Feel the Breeze
  38. AmbientAnimationTheme::kFeelTheBreeze,
  39. {
  40. // Assets
  41. {ambient::resources::kClipBottomAssetId,
  42. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_CLIP_BOTTOM_PNG},
  43. {ambient::resources::kClipTopAssetId,
  44. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_CLIP_TOP_PNG},
  45. {ambient::resources::kFrameImage1AssetId,
  46. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_FRAME_IMAGE_1_PNG},
  47. {ambient::resources::kFrameImage2AssetId,
  48. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_FRAME_IMAGE_2_PNG},
  49. {ambient::resources::kTreeShadowAssetId,
  50. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_TREE_SHADOW_PNG},
  51. {ambient::resources::kStringAssetId,
  52. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FEEL_THE_BREEZE_STRING_PNG},
  53. // End Assets
  54. }
  55. // End Theme: Feel the Breeze
  56. },
  57. {
  58. // Theme: Float on By
  59. AmbientAnimationTheme::kFloatOnBy,
  60. {
  61. // Assets
  62. {ambient::resources::kShadowA1AssetId,
  63. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_SHADOW_A_1_PNG},
  64. {ambient::resources::kShadowB1AssetId,
  65. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_SHADOW_B_1_PNG},
  66. {ambient::resources::kShadowC1AssetId,
  67. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_SHADOW_C_1_PNG},
  68. {ambient::resources::kShadowD1AssetId,
  69. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_SHADOW_D_1_PNG},
  70. {ambient::resources::kShadowE1AssetId,
  71. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_SHADOW_E_1_PNG},
  72. {ambient::resources::kShadowF1AssetId,
  73. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_SHADOW_F_1_PNG},
  74. {ambient::resources::kShadowG1AssetId,
  75. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_SHADOW_G_1_PNG},
  76. {ambient::resources::kShadowH1AssetId,
  77. IDR_ASH_AMBIENT_LOTTIE_LOTTIE_FLOAT_ON_BY_SHADOW_H_1_PNG},
  78. // End Assets
  79. }
  80. // End Theme: Float on By
  81. }
  82. // End Themes
  83. };
  84. DCHECK(m.contains(theme))
  85. << "Asset/resource ids missing for " << ToString(theme);
  86. return m.at(theme);
  87. }
  88. scoped_refptr<cc::SkottieWrapper> CreateSkottieWrapper(
  89. int lottie_json_resource_id,
  90. bool serializable) {
  91. base::StringPiece animation_json =
  92. ui::ResourceBundle::GetSharedInstance().GetRawDataResource(
  93. lottie_json_resource_id);
  94. DCHECK(!animation_json.empty());
  95. base::span<const uint8_t> lottie_data_bytes =
  96. base::as_bytes(base::make_span(animation_json));
  97. scoped_refptr<cc::SkottieWrapper> animation;
  98. if (serializable) {
  99. // Create a serializable SkottieWrapper since the SkottieWrapper may have to
  100. // be serialized and transmitted over IPC for out-of-process rasterization.
  101. animation = cc::SkottieWrapper::CreateSerializable(std::vector<uint8_t>(
  102. lottie_data_bytes.begin(), lottie_data_bytes.end()));
  103. } else {
  104. animation = cc::SkottieWrapper::CreateNonSerializable(lottie_data_bytes);
  105. }
  106. DCHECK(animation);
  107. DCHECK(animation->is_valid());
  108. return animation;
  109. }
  110. class AmbientAnimationStaticResourcesImpl
  111. : public AmbientAnimationStaticResources {
  112. public:
  113. AmbientAnimationStaticResourcesImpl(
  114. AmbientAnimationTheme theme,
  115. int lottie_json_resource_id,
  116. base::flat_map<base::StringPiece, int> asset_id_to_resource_id,
  117. bool create_serializable_skottie)
  118. : theme_(theme),
  119. animation_(CreateSkottieWrapper(lottie_json_resource_id,
  120. create_serializable_skottie)),
  121. asset_id_to_resource_id_(std::move(asset_id_to_resource_id)) {
  122. DCHECK(animation_);
  123. }
  124. AmbientAnimationStaticResourcesImpl(
  125. const AmbientAnimationStaticResourcesImpl&) = delete;
  126. AmbientAnimationStaticResourcesImpl& operator=(
  127. const AmbientAnimationStaticResourcesImpl&) = delete;
  128. ~AmbientAnimationStaticResourcesImpl() override = default;
  129. const scoped_refptr<cc::SkottieWrapper>& GetSkottieWrapper() const override {
  130. return animation_;
  131. }
  132. gfx::ImageSkia GetStaticImageAsset(
  133. base::StringPiece asset_id) const override {
  134. if (!asset_id_to_resource_id_.contains(asset_id))
  135. return gfx::ImageSkia();
  136. const gfx::ImageSkia* image =
  137. ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
  138. asset_id_to_resource_id_.at(asset_id));
  139. DCHECK(image) << asset_id;
  140. return *image;
  141. }
  142. AmbientAnimationTheme GetAmbientAnimationTheme() const override {
  143. return theme_;
  144. }
  145. private:
  146. const AmbientAnimationTheme theme_;
  147. // The skottie animation object built off of the animation json string
  148. // loaded from the resource pak.
  149. const scoped_refptr<cc::SkottieWrapper> animation_;
  150. // Map of all static image assets in this animation to their corresponding
  151. // resource ids. Points to global memory with static duration.
  152. const base::flat_map<base::StringPiece, int> asset_id_to_resource_id_;
  153. };
  154. } // namespace
  155. // static
  156. std::unique_ptr<AmbientAnimationStaticResources>
  157. AmbientAnimationStaticResources::Create(AmbientAnimationTheme theme,
  158. bool serializable) {
  159. if (!GetAnimationThemeToLottieResourceIdMap().contains(theme))
  160. return nullptr;
  161. return std::make_unique<AmbientAnimationStaticResourcesImpl>(
  162. theme, GetAnimationThemeToLottieResourceIdMap().at(theme),
  163. GetAssetIdToResourceIdMapForTheme(theme), serializable);
  164. }
  165. } // namespace ash