123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- // Copyright 2021 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 "cc/paint/skottie_wrapper.h"
- #include <cstdint>
- #include <string>
- #include <vector>
- #include "base/bind.h"
- #include "base/containers/span.h"
- #include "base/files/file_path.h"
- #include "base/memory/scoped_refptr.h"
- #include "cc/paint/skottie_mru_resource_provider.h"
- #include "cc/paint/skottie_resource_metadata.h"
- #include "cc/test/lottie_test_data.h"
- #include "cc/test/skia_common.h"
- #include "cc/test/test_skcanvas.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/skia/include/core/SkRect.h"
- #include "third_party/skia/include/core/SkSize.h"
- #include "ui/gfx/geometry/size.h"
- namespace cc {
- namespace {
- using ::testing::_;
- using ::testing::Contains;
- using ::testing::Eq;
- using ::testing::FieldsAre;
- using ::testing::FloatNear;
- using ::testing::IsEmpty;
- using ::testing::IsSupersetOf;
- using ::testing::Key;
- using ::testing::Mock;
- using ::testing::Ne;
- using ::testing::NotNull;
- using ::testing::Optional;
- using ::testing::Pair;
- using ::testing::SizeIs;
- using ::testing::UnorderedElementsAre;
- constexpr float kMarkerEpsilon = .01f;
- class MockFrameDataCallback {
- public:
- MOCK_METHOD(SkottieWrapper::FrameDataFetchResult,
- OnAssetLoaded,
- (SkottieResourceIdHash asset_id_hash,
- float t,
- sk_sp<SkImage>& image_out,
- SkSamplingOptions& sampling_out));
- SkottieWrapper::FrameDataCallback Get() {
- return base::BindRepeating(&MockFrameDataCallback::OnAssetLoaded,
- base::Unretained(this));
- }
- };
- TEST(SkottieWrapperTest, LoadsValidLottieFileNonSerializable) {
- scoped_refptr<SkottieWrapper> skottie =
- SkottieWrapper::CreateNonSerializable(base::span<const uint8_t>(
- reinterpret_cast<const uint8_t*>(kLottieDataWithoutAssets1.data()),
- kLottieDataWithoutAssets1.length()));
- EXPECT_TRUE(skottie->is_valid());
- }
- TEST(SkottieWrapperTest, LoadsValidLottieFileSerializable) {
- scoped_refptr<SkottieWrapper> skottie =
- SkottieWrapper::CreateSerializable(std::vector<uint8_t>(
- reinterpret_cast<const uint8_t*>(kLottieDataWithoutAssets1.data()),
- reinterpret_cast<const uint8_t*>(kLottieDataWithoutAssets1.data()) +
- kLottieDataWithoutAssets1.length()));
- EXPECT_TRUE(skottie->is_valid());
- }
- TEST(SkottieWrapperTest, DetectsInvalidLottieFile) {
- static constexpr base::StringPiece kInvalidJson = "this is invalid json";
- scoped_refptr<SkottieWrapper> skottie =
- SkottieWrapper::CreateNonSerializable(base::span<const uint8_t>(
- reinterpret_cast<const uint8_t*>(kInvalidJson.data()),
- kInvalidJson.length()));
- EXPECT_FALSE(skottie->is_valid());
- }
- TEST(SkottieWrapperTest, IdMatchesForSameLottieFile) {
- scoped_refptr<SkottieWrapper> skottie_1 =
- SkottieWrapper::CreateNonSerializable(base::span<const uint8_t>(
- reinterpret_cast<const uint8_t*>(kLottieDataWithoutAssets1.data()),
- kLottieDataWithoutAssets1.length()));
- scoped_refptr<SkottieWrapper> skottie_2 =
- SkottieWrapper::CreateSerializable(std::vector<uint8_t>(
- reinterpret_cast<const uint8_t*>(kLottieDataWithoutAssets1.data()),
- reinterpret_cast<const uint8_t*>(kLottieDataWithoutAssets1.data()) +
- kLottieDataWithoutAssets1.length()));
- ASSERT_TRUE(skottie_1->is_valid());
- ASSERT_TRUE(skottie_2->is_valid());
- EXPECT_THAT(skottie_1->id(), Eq(skottie_2->id()));
- }
- TEST(SkottieWrapperTest, IdDoesNotMatchForDifferentLottieFile) {
- scoped_refptr<SkottieWrapper> skottie_1 =
- SkottieWrapper::CreateNonSerializable(base::span<const uint8_t>(
- reinterpret_cast<const uint8_t*>(kLottieDataWithoutAssets1.data()),
- kLottieDataWithoutAssets1.length()));
- scoped_refptr<SkottieWrapper> skottie_2 =
- SkottieWrapper::CreateNonSerializable(base::span<const uint8_t>(
- reinterpret_cast<const uint8_t*>(kLottieDataWithoutAssets2.data()),
- kLottieDataWithoutAssets2.length()));
- ASSERT_TRUE(skottie_1->is_valid());
- ASSERT_TRUE(skottie_2->is_valid());
- EXPECT_THAT(skottie_1->id(), Ne(skottie_2->id()));
- }
- TEST(SkottieWrapperTest, LoadsImageAssetsMetadata) {
- scoped_refptr<SkottieWrapper> skottie =
- SkottieWrapper::CreateNonSerializable(base::span<const uint8_t>(
- reinterpret_cast<const uint8_t*>(kLottieDataWith2Assets.data()),
- kLottieDataWith2Assets.length()));
- ASSERT_TRUE(skottie->is_valid());
- SkottieResourceMetadataMap metadata = skottie->GetImageAssetMetadata();
- EXPECT_THAT(
- metadata.asset_storage(),
- UnorderedElementsAre(
- Pair("image_0",
- FieldsAre(base::FilePath(FILE_PATH_LITERAL("images/img_0.jpg"))
- .NormalizePathSeparators(),
- Optional(gfx::Size(kLottieDataWith2AssetsWidth,
- kLottieDataWith2AssetsHeight)))),
- Pair("image_1",
- FieldsAre(base::FilePath(FILE_PATH_LITERAL("images/img_1.jpg"))
- .NormalizePathSeparators(),
- Optional(gfx::Size(kLottieDataWith2AssetsWidth,
- kLottieDataWith2AssetsHeight))))));
- }
- TEST(SkottieWrapperTest, LoadsCorrectAssetsForDraw) {
- scoped_refptr<SkottieWrapper> skottie =
- CreateSkottieFromString(kLottieDataWith2Assets);
- ASSERT_TRUE(skottie->is_valid());
- ::testing::NiceMock<MockCanvas> canvas;
- MockFrameDataCallback mock_callback;
- EXPECT_CALL(mock_callback,
- OnAssetLoaded(HashSkottieResourceId("image_0"), _, _, _));
- skottie->Draw(&canvas, /*t=*/0.25, SkRect::MakeWH(500, 500),
- mock_callback.Get(), SkottieColorMap(),
- SkottieTextPropertyValueMap());
- Mock::VerifyAndClearExpectations(&mock_callback);
- EXPECT_CALL(mock_callback,
- OnAssetLoaded(HashSkottieResourceId("image_1"), _, _, _));
- skottie->Draw(&canvas, /*t=*/0.75, SkRect::MakeWH(500, 500),
- mock_callback.Get(), SkottieColorMap(),
- SkottieTextPropertyValueMap());
- Mock::VerifyAndClearExpectations(&mock_callback);
- }
- TEST(SkottieWrapperTest, AllowsNullFrameDataCallbackForDraw) {
- scoped_refptr<SkottieWrapper> skottie =
- CreateSkottieFromString(kLottieDataWithoutAssets1);
- ASSERT_TRUE(skottie->is_valid());
- // Just verify that this call does not cause a CHECK failure.
- ::testing::NiceMock<MockCanvas> canvas;
- skottie->Draw(&canvas, /*t=*/0, SkRect::MakeWH(500, 500),
- SkottieWrapper::FrameDataCallback(), SkottieColorMap(),
- SkottieTextPropertyValueMap());
- }
- TEST(SkottieWrapperTest, LoadsCorrectAssetsForSeek) {
- scoped_refptr<SkottieWrapper> skottie =
- CreateSkottieFromString(kLottieDataWith2Assets);
- ASSERT_TRUE(skottie->is_valid());
- ::testing::NiceMock<MockCanvas> canvas;
- MockFrameDataCallback mock_callback;
- EXPECT_CALL(mock_callback,
- OnAssetLoaded(HashSkottieResourceId("image_0"), _, _, _));
- skottie->Seek(/*t=*/0.25, mock_callback.Get());
- Mock::VerifyAndClearExpectations(&mock_callback);
- EXPECT_CALL(mock_callback,
- OnAssetLoaded(HashSkottieResourceId("image_1"), _, _, _));
- skottie->Seek(/*t=*/0.75, mock_callback.Get());
- Mock::VerifyAndClearExpectations(&mock_callback);
- }
- TEST(SkottieWrapperTest, LoadsColorNodes) {
- auto skottie = CreateSkottieFromString(kLottieDataWithoutAssets1);
- ASSERT_TRUE(skottie->is_valid());
- EXPECT_THAT(
- skottie->GetCurrentColorPropertyValues(),
- UnorderedElementsAre(
- Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color1Node),
- kLottieDataWithoutAssets1Color1),
- Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
- kLottieDataWithoutAssets1Color2)));
- }
- TEST(SkottieWrapperTest, SetsColorNodesWithDraw) {
- auto skottie = CreateSkottieFromString(kLottieDataWithoutAssets1);
- ASSERT_TRUE(skottie->is_valid());
- ::testing::NiceMock<MockCanvas> canvas;
- SkottieColorMap color_map = {
- {HashSkottieResourceId(kLottieDataWithoutAssets1Color1Node),
- SK_ColorYELLOW},
- {HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
- SK_ColorCYAN}};
- skottie->Draw(&canvas, /*t=*/0, SkRect::MakeWH(500, 500),
- SkottieWrapper::FrameDataCallback(), color_map,
- SkottieTextPropertyValueMap());
- EXPECT_THAT(
- skottie->GetCurrentColorPropertyValues(),
- UnorderedElementsAre(
- Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color1Node),
- SK_ColorYELLOW),
- Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
- SK_ColorCYAN)));
- color_map = {{HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
- SK_ColorMAGENTA}};
- skottie->Draw(&canvas, /*t=*/0, SkRect::MakeWH(500, 500),
- SkottieWrapper::FrameDataCallback(), color_map,
- SkottieTextPropertyValueMap());
- EXPECT_THAT(
- skottie->GetCurrentColorPropertyValues(),
- UnorderedElementsAre(
- Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color1Node),
- SK_ColorYELLOW),
- Pair(HashSkottieResourceId(kLottieDataWithoutAssets1Color2Node),
- SK_ColorMAGENTA)));
- }
- TEST(SkottieWrapperTest, LoadsTextNodes) {
- auto skottie = CreateSkottieFromTestDataDir(kLottieDataWith2TextFileName);
- ASSERT_TRUE(skottie->is_valid());
- EXPECT_THAT(skottie->GetTextNodeNames(),
- UnorderedElementsAre(kLottieDataWith2TextNode1,
- kLottieDataWith2TextNode2));
- EXPECT_THAT(skottie->GetCurrentTextPropertyValues(),
- UnorderedElementsAre(
- Pair(HashSkottieResourceId(kLottieDataWith2TextNode1),
- SkottieTextPropertyValue(
- std::string(kLottieDataWith2TextNode1Text),
- kLottieDataWith2TextNode1Box)),
- Pair(HashSkottieResourceId(kLottieDataWith2TextNode2),
- SkottieTextPropertyValue(
- std::string(kLottieDataWith2TextNode2Text),
- kLottieDataWith2TextNode2Box))));
- }
- TEST(SkottieWrapperTest, SetsTextNodesWithDraw) {
- auto skottie = CreateSkottieFromTestDataDir(kLottieDataWith2TextFileName);
- ASSERT_TRUE(skottie->is_valid());
- ::testing::NiceMock<MockCanvas> canvas;
- SkottieTextPropertyValueMap text_map = {
- {HashSkottieResourceId(kLottieDataWith2TextNode1),
- SkottieTextPropertyValue("new-test-text-1", gfx::RectF(1, 1, 1, 1))},
- {HashSkottieResourceId(kLottieDataWith2TextNode2),
- SkottieTextPropertyValue("new-test-text-2", gfx::RectF(2, 2, 2, 2))}};
- skottie->Draw(&canvas, /*t=*/0, SkRect::MakeWH(500, 500),
- SkottieWrapper::FrameDataCallback(), SkottieColorMap(),
- text_map);
- EXPECT_THAT(skottie->GetCurrentTextPropertyValues(),
- UnorderedElementsAre(
- Pair(HashSkottieResourceId(kLottieDataWith2TextNode1),
- SkottieTextPropertyValue("new-test-text-1",
- gfx::RectF(1, 1, 1, 1))),
- Pair(HashSkottieResourceId(kLottieDataWith2TextNode2),
- SkottieTextPropertyValue("new-test-text-2",
- gfx::RectF(2, 2, 2, 2)))));
- text_map = {
- {HashSkottieResourceId(kLottieDataWith2TextNode2),
- SkottieTextPropertyValue("new-test-text-2b", gfx::RectF(3, 3, 3, 3))}};
- skottie->Draw(&canvas, /*t=*/0.1, SkRect::MakeWH(500, 500),
- SkottieWrapper::FrameDataCallback(), SkottieColorMap(),
- text_map);
- EXPECT_THAT(skottie->GetCurrentTextPropertyValues(),
- UnorderedElementsAre(
- Pair(HashSkottieResourceId(kLottieDataWith2TextNode1),
- SkottieTextPropertyValue("new-test-text-1",
- gfx::RectF(1, 1, 1, 1))),
- Pair(HashSkottieResourceId(kLottieDataWith2TextNode2),
- SkottieTextPropertyValue("new-test-text-2b",
- gfx::RectF(3, 3, 3, 3)))));
- }
- TEST(SkottieWrapperTest, Marker) {
- auto skottie = CreateSkottieFromString(kLottieDataWith2Markers);
- ASSERT_TRUE(skottie->is_valid());
- EXPECT_THAT(
- skottie->GetAllMarkers(),
- UnorderedElementsAre(
- FieldsAre(
- kLottieDataWith2MarkersMarker1,
- FloatNear(kLottieDataWith2MarkersMarker1Time, kMarkerEpsilon),
- FloatNear(kLottieDataWith2MarkersMarker1Time, kMarkerEpsilon)),
- FieldsAre(
- kLottieDataWith2MarkersMarker2,
- FloatNear(kLottieDataWith2MarkersMarker2Time, kMarkerEpsilon),
- FloatNear(kLottieDataWith2MarkersMarker2Time, kMarkerEpsilon))));
- }
- TEST(SkottieWrapperTest, LoadsTransformNodes) {
- auto skottie = CreateSkottieFromTestDataDir(kLottieDataWith2TextFileName);
- ASSERT_TRUE(skottie->is_valid());
- EXPECT_THAT(skottie->GetTextNodeNames(),
- UnorderedElementsAre(kLottieDataWith2TextNode1,
- kLottieDataWith2TextNode2));
- EXPECT_THAT(
- skottie->GetCurrentTransformPropertyValues(),
- IsSupersetOf({Pair(HashSkottieResourceId(kLottieDataWith2TextNode1),
- SkottieTransformPropertyValue(
- {kLottieDataWith2TextNode1Position})),
- Pair(HashSkottieResourceId(kLottieDataWith2TextNode2),
- SkottieTransformPropertyValue(
- {kLottieDataWith2TextNode2Position}))}));
- }
- } // namespace
- } // namespace cc
|