0

Serialize SkPath with mojo

This is required for making corner-shape and backdrop-filter work well
together (the path need to be propagated all the way to viz).

This uses the internal serialization mechanism of SkPath, and saves it
into a mojo array<uint8>. The path is "opaque" but can be serialized
to/from an SkPath.

Bug: 408498304
Change-Id: I606dc0e78789cda1552bcd4c55a84958b5ba3a91
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6434053
Reviewed-by: Robert Phillips <robertphillips@google.com>
Reviewed-by: Mike West <mkwst@chromium.org>
Commit-Queue: Noam Rosenthal <nrosenthal@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1443511}
This commit is contained in:
Noam Rosenthal
2025-04-07 08:51:32 -07:00
committed by Chromium LUCI CQ
parent 9494ad99b1
commit d041d6d90a
4 changed files with 82 additions and 0 deletions

@ -38,6 +38,7 @@ mojom("mojom") {
"skcolor4f.mojom",
"skcolorspace.mojom",
"skcolorspace_primaries.mojom",
"skpath.mojom",
"surface_origin.mojom",
"tile_mode.mojom",
]
@ -150,6 +151,16 @@ mojom("mojom") {
traits_headers = [ "skcolorspace_mojom_traits.h" ]
traits_public_deps = [ "//skia" ]
},
{
types = [
{
mojom = "skia.mojom.SkPath"
cpp = "::SkPath"
},
]
traits_headers = [ "skpath_mojom_traits.h" ]
traits_public_deps = [ "//skia" ]
},
{
types = [
{

@ -0,0 +1,13 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file contains structures used to represent an SkPath in Mojo.
module skia.mojom;
// Represents a serialized version of SkPath
// It uses SkPath's internal serialization format and passes the resulting
// buffer to mojo.
struct SkPath {
array<uint8> data;
};

@ -0,0 +1,33 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_PUBLIC_MOJOM_SKPATH_MOJOM_TRAITS_H_
#define SKIA_PUBLIC_MOJOM_SKPATH_MOJOM_TRAITS_H_
#include <vector>
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "skia/public/mojom/skpath.mojom-shared.h"
#include "third_party/skia/include/core/SkPath.h"
namespace mojo {
template <>
struct StructTraits<skia::mojom::SkPathDataView, ::SkPath> {
static std::vector<uint8_t> data(const SkPath& path) {
std::vector<uint8_t> buffer(path.writeToMemory(nullptr));
CHECK_EQ(path.writeToMemory(buffer.data()), buffer.size());
return buffer;
}
static bool Read(skia::mojom::SkPathDataView data, ::SkPath* path) {
std::vector<uint8_t> buffer;
return data.ReadData(&buffer) &&
path->readFromMemory(buffer.data(), buffer.size());
}
};
} // namespace mojo
#endif // SKIA_PUBLIC_MOJOM_SKPATH_MOJOM_TRAITS_H_

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "include/core/SkPathBuilder.h"
#include "include/core/SkRRect.h"
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/390223051): Remove C-library calls to fix the errors.
#pragma allow_unsafe_libc_calls
@ -19,12 +21,15 @@
#include "skia/public/mojom/skcolorspace_mojom_traits.h"
#include "skia/public/mojom/skcolorspace_primaries.mojom.h"
#include "skia/public/mojom/skcolorspace_primaries_mojom_traits.h"
#include "skia/public/mojom/skpath.mojom.h"
#include "skia/public/mojom/skpath_mojom_traits.h"
#include "skia/public/mojom/tile_mode.mojom.h"
#include "skia/public/mojom/tile_mode_mojom_traits.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkString.h"
#include "third_party/skia/include/core/SkTileMode.h"
#include "third_party/skia/modules/skcms/skcms.h"
@ -98,6 +103,14 @@ mojo::StructPtr<skia::mojom::ImageInfo> ConstructImageInfo(
return mojom_info;
}
void TestSkPathSerialization(const SkPath& input) {
SkPath output;
ASSERT_TRUE(
mojo::test::SerializeAndDeserialize<skia::mojom::SkPath>(input, output));
EXPECT_EQ(input, output);
}
TEST(StructTraitsTest, ImageInfo) {
SkImageInfo input = SkImageInfo::Make(
34, 56, SkColorType::kGray_8_SkColorType,
@ -212,6 +225,18 @@ TEST(StructTraitsTest, TileMode) {
EXPECT_EQ(input, output);
}
TEST(StructTraitsTest, SkPath) {
TestSkPathSerialization(SkPath::Rect(SkRect::MakeWH(100, 200)));
TestSkPathSerialization(SkPath::Circle(100, 0, 30));
TestSkPathSerialization(
SkPath::Polygon({{0, 10}, {10, 0}, {10, 10}}, /*isClosed=*/true));
TestSkPathSerialization(SkPathBuilder()
.addRRect(SkRRect::MakeRectXY(
SkRect::MakeLTRB(10, 10, 30, 50), 2.5, 3))
.cubicTo({0, 10}, {30, 50}, {-5, .8})
.detach());
}
TEST(StructTraitsTest, Bitmap) {
SkBitmap input;
input.allocPixels(SkImageInfo::MakeN32Premul(