| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_PAINT_PREVIEW_COMMON_SERIALIZED_RECORDING_H_ |
| #define COMPONENTS_PAINT_PREVIEW_COMMON_SERIALIZED_RECORDING_H_ |
| |
| #include <optional> |
| |
| #include "base/files/file.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/unguessable_token.h" |
| #include "components/paint_preview/common/mojom/paint_preview_types.mojom-shared.h" |
| #include "components/paint_preview/common/serial_utils.h" |
| #include "mojo/public/cpp/base/big_buffer.h" |
| #include "mojo/public/cpp/bindings/union_traits.h" |
| #include "third_party/skia/include/core/SkRefCnt.h" |
| |
| class SkPicture; |
| |
| namespace paint_preview { |
| |
| class PaintPreviewTracker; |
| |
| // Enumeration of strategies to store artifacts (i.e. frame recordings) of a |
| // paint preview capture. |
| enum class RecordingPersistence { |
| // Store artifacts in the file system. This strategy can be robust to browser |
| // restarts, since the lifetime of the files can outlive the browser process. |
| kFileSystem, |
| |
| // Store artifacts in memory buffers returned from or passed to capture or |
| // compositing methods. On low-memory devices, there is a higher risk of |
| // out-of-memory issues. |
| kMemoryBuffer, |
| }; |
| |
| // Struct for containing an SkPicture and its deserialization context. |
| struct SkpResult { |
| SkpResult(); |
| ~SkpResult(); |
| |
| SkpResult(const SkpResult& other) = delete; |
| SkpResult& operator=(const SkpResult& rhs) = delete; |
| |
| SkpResult(SkpResult&& other); |
| SkpResult& operator=(SkpResult&& rhs); |
| |
| sk_sp<SkPicture> skp; |
| DeserializationContext ctx; |
| }; |
| |
| // This is an object that contains the serialized |SkPicture| that results from |
| // a rendering frame recording. It will be backed by a value corresponding to |
| // its |persistence_| value. |
| // |
| // The contents of a |SerializedRecording| must be generated by |RecordToFile| |
| // or |RecordToBuffer| to be safely deserialized. |
| class SerializedRecording { |
| public: |
| // Create an invalid variant, which doesn't have a valid file or buffer. |
| SerializedRecording(); |
| |
| // Create a file variant. Will open a file at the given path for reading. |
| explicit SerializedRecording(base::FilePath); |
| |
| // Create a memory buffer variant. |
| explicit SerializedRecording(mojo_base::BigBuffer); |
| |
| SerializedRecording(SerializedRecording&&); |
| SerializedRecording& operator=(SerializedRecording&&); |
| ~SerializedRecording(); |
| |
| // Returns true if this contains a valid value for its variant. |
| bool IsValid() const; |
| |
| private: |
| friend struct mojo::UnionTraits< |
| paint_preview::mojom::SerializedRecordingDataView, |
| paint_preview::SerializedRecording>; |
| |
| // Expose |Deserialize| only to places that will use it safely (i.e. not on |
| // the browser process). |
| friend class PaintPreviewCompositorImpl; |
| friend class PaintPreviewBrowserTest; |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewSerializedRecordingTest, |
| RoundtripWithFileBacking); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewSerializedRecordingTest, |
| RoundtripWithMemoryBufferBacking); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewSerializedRecordingTest, |
| RoundtripHasEmbeddedContent); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewSerializedRecordingTest, |
| RecordingMapFromCaptureResultSingleFrame); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewSerializedRecordingTest, |
| RecordingMapFromPaintPreviewProtoSingleFrame); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewRecorderUtilsSerializeAsSkPictureTest, |
| Roundtrip); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewRecorderUtilsSerializeAsSkPictureTest, |
| RoundtripWithImage); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewRecorderUtilsSerializeAsSkPictureTest, |
| RoundtripWithLazyImage); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewRecorderUtilsSerializeAsSkPictureTest, |
| RoundtripWithPaintWorklet); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewRecorderUtilsSerializeAsSkPictureTest, |
| RoundtripWithTexture); |
| FRIEND_TEST_ALL_PREFIXES(PaintPreviewRecorderUtilsSerializeAsSkPictureTest, |
| RoundtripWithLazyTexture); |
| |
| // Deserialize into an |SkPicture|. The result will not include any embedded |
| // subframes. |
| // |
| // This is not safe to call in the browser process. |
| std::optional<SkpResult> Deserialize() &&; |
| |
| // Deserialize into an |SkPicture|. |ctx| should contain entries for any |
| // subframes that should be included in the output. |
| // |
| // This is not safe to call in the browser process. |
| sk_sp<SkPicture> DeserializeWithContext(LoadedFramesDeserialContext* ctx) &&; |
| |
| // Create a file variant from an existing file. File must have been created |
| // with the flags: base::File::FLAG_OPEN | base::File::FLAG_READ. |
| explicit SerializedRecording(base::File); |
| |
| bool is_file() const { |
| return persistence_ == RecordingPersistence::kFileSystem; |
| } |
| |
| bool is_buffer() const { |
| return persistence_ == RecordingPersistence::kMemoryBuffer; |
| } |
| |
| RecordingPersistence persistence_; |
| |
| base::File file_; |
| std::optional<mojo_base::BigBuffer> buffer_; |
| }; |
| |
| // Serialize and write |skp| to |file|. |
| // |
| // If |max_size| is set, it is a limit on the total serialized size, else the |
| // capture will be unrestricted in size. If |max_size| is exceeded the |
| // serialization will fail. |serialized_size| will contain the size of the |
| // serialized output. |
| // |
| // Returns |true| on success. |
| bool RecordToFile(base::File file, |
| sk_sp<const SkPicture> skp, |
| PaintPreviewTracker* tracker, |
| std::optional<size_t> max_capture_size, |
| size_t* serialized_size); |
| |
| // Serialize and write |recording| to a memory buffer. |
| // |
| // If |max_size| is set, it is a limit on the total serialized size, else the |
| // capture will be unrestricted in size. If |max_size| is exceeded the |
| // serialization will fail. |serialized_size| will contain the size of the |
| // serialized output. |
| // |
| // Returns the memory buffer on success. |
| std::optional<mojo_base::BigBuffer> RecordToBuffer( |
| sk_sp<const SkPicture> skp, |
| PaintPreviewTracker* tracker, |
| std::optional<size_t> max_capture_size, |
| size_t* serialized_size); |
| |
| } // namespace paint_preview |
| |
| #endif // COMPONENTS_PAINT_PREVIEW_COMMON_SERIALIZED_RECORDING_H_ |