5#define FML_USED_ON_EMBEDDER
13#include "third_party/skia/include/core/SkCPURecorder.h"
14#include "third_party/skia/include/core/SkImage.h"
15#include "third_party/skia/include/core/SkSurface.h"
16#include "third_party/skia/include/encode/SkPngEncoder.h"
17#include "third_party/skia/include/gpu/ganesh/SkSurfaceGanesh.h"
23 GrDirectContext* context) {
24 const auto image_info =
26 auto surface = context ? SkSurfaces::RenderTarget(
31 kTopLeft_GrSurfaceOrigin,
36 : SkSurfaces::Raster(image_info);
44 sk_sp<SkColorSpace> norm_colorspace = SkColorSpace::MakeRGB(
45 SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020);
46 SkImageInfo norm_image_info =
47 SkImageInfo::Make(
image->width(),
image->height(),
48 SkColorType::kR16G16B16A16_unorm_SkColorType,
49 SkAlphaType::kUnpremul_SkAlphaType, norm_colorspace);
50 size_t row_bytes = norm_image_info.minRowBytes();
51 size_t size = norm_image_info.computeByteSize(row_bytes);
52 sk_sp<SkData>
data = SkData::MakeUninitialized(
size);
54 FML_CHECK(
false) <<
"Unable to allocate data.";
57 bool success =
image->readPixels(norm_image_info,
data->writable_data(),
60 FML_CHECK(
false) <<
"Unable to read pixels.";
77 return normalized_a->equals(normalized_b.get());
81 const std::string&
name) {
92 bool opengl_framebuffer) {
97 if (opengl_framebuffer) {
112 bool opengl_framebuffer) {
118 if (opengl_framebuffer) {
136 const std::string&
name,
137 const sk_sp<SkImage>&
image) {
142 auto data = SkPngEncoder::Encode(
nullptr,
image.get(), {});
150 return WriteAtomically(directory,
name.c_str(), mapping);
154 const sk_sp<SkImage>& scene_image) {
158 <<
"Could not find fixture: " << fixture_file_name;
160 auto encoded_image = SkData::MakeWithoutCopy(
163 SkImages::DeferredFromEncodedData(std::move(encoded_image))
164 ->makeRasterImage(
nullptr);
166 FML_CHECK(fixture_image) <<
"Could not create image from fixture: "
167 << fixture_file_name;
169 FML_CHECK(scene_image) <<
"Invalid scene image.";
171 auto scene_image_subset = scene_image->makeSubset(
172 skcpu::Recorder::TODO(),
173 SkIRect::MakeWH(fixture_image->width(), fixture_image->height()), {});
176 <<
"Could not create image subset for fixture comparison: "
177 << scene_image_subset;
179 const auto images_are_same =
185 if (!images_are_same) {
188 const auto actual_file_name =
"actual_" + fixture_file_name;
189 const auto expect_file_name =
"expectation_" + fixture_file_name;
195 <<
"Could not write file to disk: " << actual_file_name;
198 <<
"Could not write file to disk: " << expect_file_name;
200 FML_LOG(ERROR) <<
"Image did not match expectation." << std::endl
208 return images_are_same;
212 std::future<sk_sp<SkImage>>& scene_image) {
217 const std::vector<uint8_t>& bytes) {
219 auto ok =
surface->peekPixels(&pixmap);
224 auto matches = (pixmap.rowBytes() == bytes.size()) &&
225 (memcmp(bytes.data(), pixmap.addr(), bytes.size()) == 0);
228 FML_LOG(ERROR) <<
"SkImage pixel data didn't match bytes.";
231 const uint8_t* addr =
static_cast<const uint8_t*
>(pixmap.addr());
232 std::stringstream stream;
233 for (
size_t i = 0;
i < pixmap.computeByteSize(); ++
i) {
234 stream <<
"0x" << std::setfill(
'0') << std::setw(2) << std::uppercase
235 << std::hex << static_cast<int>(addr[
i]);
236 if (
i != pixmap.computeByteSize() - 1) {
240 FML_LOG(ERROR) <<
" Actual: " << stream.str();
243 std::stringstream stream;
244 for (
auto b = bytes.begin(); b != bytes.end(); ++b) {
245 stream <<
"0x" << std::setfill(
'0') << std::setw(2) << std::uppercase
246 << std::hex << static_cast<int>(*b);
247 if (b != bytes.end() - 1) {
251 FML_LOG(ERROR) <<
" Expected: " << stream.str();
259 const std::vector<uint8_t>& bytes) {
269 if (mutations ==
nullptr) {
273 for (
size_t i = 0;
i < count; ++
i) {
299 [&](
const auto& mutation) {
300 collected = collected *
DlMatrixMake(mutation.transformation);
308 view->mutations_count);
size_t GetSize() const override
const uint8_t * GetMapping() const override
FlutterPlatformViewMutationType
@ kFlutterPlatformViewMutationTypeTransformation
@ kFlutterOpenGLTargetTypeFramebuffer
@ kFlutterOpenGLTargetTypeTexture
@ kFlutterBackingStoreTypeMetal
Specifies a Metal backing store. This is backed by a Metal texture.
@ kFlutterBackingStoreTypeVulkan
Specifies a Vulkan backing store. This is backed by a Vulkan VkImage.
@ kFlutterBackingStoreTypeSoftware
Specified an software allocation for Flutter to render into using the CPU.
@ kFlutterBackingStoreTypeOpenGL
flutter::DlMatrix DlMatrixMake(const FlutterTransformation &xformation)
FlutterVulkanImage * image
const gchar FlBinaryMessengerMessageHandler handler
#define FML_LOG(severity)
#define FML_CHECK(condition)
const char * GetFixturesPath()
Returns the directory containing the test fixture for the target if this target has fixtures configur...
bool WriteImageToDisk(const fml::UniqueFD &directory, const std::string &name, const sk_sp< SkImage > &image)
sk_sp< SkSurface > CreateRenderSurface(const FlutterLayer &layer, GrDirectContext *context)
void FilterMutationsByType(const FlutterPlatformViewMutation **mutations, size_t count, FlutterPlatformViewMutationType type, const std::function< void(const FlutterPlatformViewMutation &mutation)> &handler)
static sk_sp< SkData > NormalizeImage(const sk_sp< SkImage > &image)
bool SurfacePixelDataMatchesBytes(SkSurface *surface, const std::vector< uint8_t > &bytes)
fml::UniqueFD OpenFixture(const std::string &fixture_name)
Opens a fixture of the given file name.
fml::UniqueFD OpenFixturesDirectory()
Opens the fixtures directory for the unit-test harness.
void ConfigureBackingStore(FlutterBackingStore &backing_store, EmbedderTestContextType backend, bool opengl_framebuffer)
Configures per-backend properties for a given backing store.
bool RasterImagesAreSame(const sk_sp< SkImage > &a, const sk_sp< SkImage > &b)
std::string FixtureNameForBackend(EmbedderTestContextType backend, const std::string &name)
Prepends a prefix to the name which is unique to the test context type. This is useful for tests that...
bool ImageMatchesFixture(const std::string &fixture_file_name, const sk_sp< SkImage > &scene_image)
EmbedderTestBackingStoreProducer::RenderTargetType GetRenderTargetFromBackend(EmbedderTestContextType backend, bool opengl_framebuffer)
Resolves a render target type for a given backend description. This is useful for tests that use Embe...
DlMatrix GetTotalMutationTransformationMatrix(const FlutterPlatformViewMutation **mutations, size_t count)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library name
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
std::string JoinPaths(std::initializer_list< std::string > components)
FlutterBackingStoreType type
Specifies the type of backing store.
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
FlutterSize size
The size of the layer (in physical pixels).
FlutterOpenGLTargetType type
A 4x4 matrix using column-major storage.