blob: 30fd28488bc00c19a27c93dacb392cbc6db78ac9 [file] [log] [blame]
// 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_