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.";
67 const sk_sp<SkImage>& b,
68 int allowable_different_pixels) {
79 if (normalized_a->size() != normalized_b->size()) {
82 using NormalizedPixel = uint64_t;
83 FML_CHECK(normalized_a->size() %
sizeof(NormalizedPixel) == 0);
85 for (
size_t i = 0;
i < normalized_a->size();
i +=
sizeof(NormalizedPixel)) {
86 const NormalizedPixel* pixel_a =
87 reinterpret_cast<const NormalizedPixel*
>(normalized_a->bytes() +
i);
88 const NormalizedPixel* pixel_b =
89 reinterpret_cast<const NormalizedPixel*
>(normalized_b->bytes() +
i);
90 if (*pixel_a != *pixel_b) {
92 if (diff_count > allowable_different_pixels) {
102 const std::string&
name) {
113 bool opengl_framebuffer) {
118 if (opengl_framebuffer) {
133 bool opengl_framebuffer) {
139 if (opengl_framebuffer) {
157 const std::string&
name,
158 const sk_sp<SkImage>&
image) {
163 auto data = SkPngEncoder::Encode(
nullptr,
image.get(), {});
171 return WriteAtomically(directory,
name.c_str(), mapping);
175 const sk_sp<SkImage>& scene_image,
176 int allowable_different_pixels) {
180 <<
"Could not find fixture: " << fixture_file_name;
182 auto encoded_image = SkData::MakeWithoutCopy(
185 SkImages::DeferredFromEncodedData(std::move(encoded_image))
186 ->makeRasterImage(
nullptr);
188 FML_CHECK(fixture_image) <<
"Could not create image from fixture: "
189 << fixture_file_name;
191 FML_CHECK(scene_image) <<
"Invalid scene image.";
193 auto scene_image_subset = scene_image->makeSubset(
194 skcpu::Recorder::TODO(),
195 SkIRect::MakeWH(fixture_image->width(), fixture_image->height()), {});
198 <<
"Could not create image subset for fixture comparison: "
199 << scene_image_subset;
202 scene_image_subset, fixture_image, allowable_different_pixels);
207 if (!images_are_same) {
210 const auto actual_file_name =
"actual_" + fixture_file_name;
211 const auto expect_file_name =
"expectation_" + fixture_file_name;
217 <<
"Could not write file to disk: " << actual_file_name;
220 <<
"Could not write file to disk: " << expect_file_name;
222 FML_LOG(ERROR) <<
"Image did not match expectation." << std::endl
230 return images_are_same;
234 std::future<sk_sp<SkImage>>& scene_image,
235 int allowable_different_pixels) {
237 allowable_different_pixels);
241 const std::vector<uint8_t>& bytes) {
243 auto ok =
surface->peekPixels(&pixmap);
248 auto matches = (pixmap.rowBytes() == bytes.size()) &&
249 (memcmp(bytes.data(), pixmap.addr(), bytes.size()) == 0);
252 FML_LOG(ERROR) <<
"SkImage pixel data didn't match bytes.";
255 const uint8_t* addr =
static_cast<const uint8_t*
>(pixmap.addr());
256 std::stringstream stream;
257 for (
size_t i = 0;
i < pixmap.computeByteSize(); ++
i) {
258 stream <<
"0x" << std::setfill(
'0') << std::setw(2) << std::uppercase
259 << std::hex << static_cast<int>(addr[
i]);
260 if (
i != pixmap.computeByteSize() - 1) {
264 FML_LOG(ERROR) <<
" Actual: " << stream.str();
267 std::stringstream stream;
268 for (
auto b = bytes.begin(); b != bytes.end(); ++b) {
269 stream <<
"0x" << std::setfill(
'0') << std::setw(2) << std::uppercase
270 << std::hex << static_cast<int>(*b);
271 if (b != bytes.end() - 1) {
275 FML_LOG(ERROR) <<
" Expected: " << stream.str();
283 const std::vector<uint8_t>& bytes) {
293 if (mutations ==
nullptr) {
297 for (
size_t i = 0;
i < count; ++
i) {
323 [&](
const auto& mutation) {
324 collected = collected *
DlMatrixMake(mutation.transformation);
332 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)
bool ImageMatchesFixture(const std::string &fixture_file_name, const sk_sp< SkImage > &scene_image, int allowable_different_pixels)
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.
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...
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...
bool RasterImagesAreSame(const sk_sp< SkImage > &a, const sk_sp< SkImage > &b, int allowable_different_pixels)
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)
impeller::ShaderType type
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.