mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Compiling with clang on Windows fails here with a warning about implicit cast from function pointer to object pointer. Rather than disable that warning, this makes it an explicit cast. Since this is just test output, it's not critical that this be a completely safe operation. Part of #16256
454 lines
16 KiB
C++
454 lines
16 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_ASSERTIONS_H_
|
|
#define FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_ASSERTIONS_H_
|
|
|
|
#include <sstream>
|
|
|
|
#include "flutter/fml/logging.h"
|
|
#include "flutter/shell/platform/embedder/embedder.h"
|
|
#include "flutter/shell/platform/embedder/embedder_engine.h"
|
|
#include "flutter/testing/assertions.h"
|
|
#include "gtest/gtest.h"
|
|
#include "third_party/skia/include/core/SkPoint.h"
|
|
#include "third_party/skia/include/core/SkSize.h"
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Equality
|
|
//------------------------------------------------------------------------------
|
|
inline bool operator==(const FlutterPoint& a, const FlutterPoint& b) {
|
|
return flutter::testing::NumberNear(a.x, b.x) &&
|
|
flutter::testing::NumberNear(a.y, b.y);
|
|
}
|
|
|
|
inline bool operator==(const FlutterRect& a, const FlutterRect& b) {
|
|
return flutter::testing::NumberNear(a.left, b.left) &&
|
|
flutter::testing::NumberNear(a.top, b.top) &&
|
|
flutter::testing::NumberNear(a.right, b.right) &&
|
|
flutter::testing::NumberNear(a.bottom, b.bottom);
|
|
}
|
|
|
|
inline bool operator==(const FlutterSize& a, const FlutterSize& b) {
|
|
return flutter::testing::NumberNear(a.width, b.width) &&
|
|
flutter::testing::NumberNear(a.height, b.height);
|
|
}
|
|
|
|
inline bool operator==(const FlutterRoundedRect& a,
|
|
const FlutterRoundedRect& b) {
|
|
return a.rect == b.rect &&
|
|
a.upper_left_corner_radius == b.upper_left_corner_radius &&
|
|
a.upper_right_corner_radius == b.upper_right_corner_radius &&
|
|
a.lower_right_corner_radius == b.lower_right_corner_radius &&
|
|
a.lower_left_corner_radius == b.lower_left_corner_radius;
|
|
}
|
|
|
|
inline bool operator==(const FlutterTransformation& a,
|
|
const FlutterTransformation& b) {
|
|
return a.scaleX == b.scaleX && a.skewX == b.skewX && a.transX == b.transX &&
|
|
a.skewY == b.skewY && a.scaleY == b.scaleY && a.transY == b.transY &&
|
|
a.pers0 == b.pers0 && a.pers1 == b.pers1 && a.pers2 == b.pers2;
|
|
}
|
|
|
|
inline bool operator==(const FlutterOpenGLTexture& a,
|
|
const FlutterOpenGLTexture& b) {
|
|
return a.target == b.target && a.name == b.name && a.format == b.format &&
|
|
a.user_data == b.user_data &&
|
|
a.destruction_callback == b.destruction_callback;
|
|
}
|
|
|
|
inline bool operator==(const FlutterOpenGLFramebuffer& a,
|
|
const FlutterOpenGLFramebuffer& b) {
|
|
return a.target == b.target && a.name == b.name &&
|
|
a.user_data == b.user_data &&
|
|
a.destruction_callback == b.destruction_callback;
|
|
}
|
|
|
|
inline bool operator==(const FlutterOpenGLBackingStore& a,
|
|
const FlutterOpenGLBackingStore& b) {
|
|
if (!(a.type == b.type)) {
|
|
return false;
|
|
}
|
|
|
|
switch (a.type) {
|
|
case kFlutterOpenGLTargetTypeTexture:
|
|
return a.texture == b.texture;
|
|
case kFlutterOpenGLTargetTypeFramebuffer:
|
|
return a.framebuffer == b.framebuffer;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool operator==(const FlutterSoftwareBackingStore& a,
|
|
const FlutterSoftwareBackingStore& b) {
|
|
return a.allocation == b.allocation && a.row_bytes == b.row_bytes &&
|
|
a.height == b.height && a.user_data == b.user_data &&
|
|
a.destruction_callback == b.destruction_callback;
|
|
}
|
|
|
|
inline bool operator==(const FlutterBackingStore& a,
|
|
const FlutterBackingStore& b) {
|
|
if (!(a.struct_size == b.struct_size && a.user_data == b.user_data &&
|
|
a.type == b.type && a.did_update == b.did_update)) {
|
|
return false;
|
|
}
|
|
|
|
switch (a.type) {
|
|
case kFlutterBackingStoreTypeOpenGL:
|
|
return a.open_gl == b.open_gl;
|
|
case kFlutterBackingStoreTypeSoftware:
|
|
return a.software == b.software;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool operator==(const FlutterPlatformViewMutation& a,
|
|
const FlutterPlatformViewMutation& b) {
|
|
if (a.type != b.type) {
|
|
return false;
|
|
}
|
|
|
|
switch (a.type) {
|
|
case kFlutterPlatformViewMutationTypeOpacity:
|
|
return flutter::testing::NumberNear(a.opacity, b.opacity);
|
|
case kFlutterPlatformViewMutationTypeClipRect:
|
|
return a.clip_rect == b.clip_rect;
|
|
case kFlutterPlatformViewMutationTypeClipRoundedRect:
|
|
return a.clip_rounded_rect == b.clip_rounded_rect;
|
|
case kFlutterPlatformViewMutationTypeTransformation:
|
|
return a.transformation == b.transformation;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
inline bool operator==(const FlutterPlatformView& a,
|
|
const FlutterPlatformView& b) {
|
|
if (!(a.struct_size == b.struct_size && a.identifier == b.identifier &&
|
|
a.mutations_count == b.mutations_count)) {
|
|
return false;
|
|
}
|
|
|
|
for (size_t i = 0; i < a.mutations_count; ++i) {
|
|
if (!(*a.mutations[i] == *b.mutations[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
inline bool operator==(const FlutterLayer& a, const FlutterLayer& b) {
|
|
if (!(a.struct_size == b.struct_size && a.type == b.type &&
|
|
a.offset == b.offset && a.size == b.size)) {
|
|
return false;
|
|
}
|
|
|
|
switch (a.type) {
|
|
case kFlutterLayerContentTypeBackingStore:
|
|
return *a.backing_store == *b.backing_store;
|
|
case kFlutterLayerContentTypePlatformView:
|
|
return *a.platform_view == *b.platform_view;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Printing
|
|
//------------------------------------------------------------------------------
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, const FlutterPoint& point) {
|
|
return out << "(" << point.x << ", " << point.y << ")";
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, const FlutterRect& r) {
|
|
return out << "LTRB (" << r.left << ", " << r.top << ", " << r.right << ", "
|
|
<< r.bottom << ")";
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, const FlutterSize& size) {
|
|
return out << "(" << size.width << ", " << size.height << ")";
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterRoundedRect& r) {
|
|
out << "Rect: " << r.rect << ", ";
|
|
out << "Upper Left Corner Radius: " << r.upper_left_corner_radius << ", ";
|
|
out << "Upper Right Corner Radius: " << r.upper_right_corner_radius << ", ";
|
|
out << "Lower Right Corner Radius: " << r.lower_right_corner_radius << ", ";
|
|
out << "Lower Left Corner Radius: " << r.lower_left_corner_radius;
|
|
return out;
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterTransformation& t) {
|
|
out << "Scale X: " << t.scaleX << ", ";
|
|
out << "Skew X: " << t.skewX << ", ";
|
|
out << "Trans X: " << t.transX << ", ";
|
|
out << "Skew Y: " << t.skewY << ", ";
|
|
out << "Scale Y: " << t.scaleY << ", ";
|
|
out << "Trans Y: " << t.transY << ", ";
|
|
out << "Pers 0: " << t.pers0 << ", ";
|
|
out << "Pers 1: " << t.pers1 << ", ";
|
|
out << "Pers 2: " << t.pers2;
|
|
return out;
|
|
}
|
|
|
|
inline std::string FlutterLayerContentTypeToString(
|
|
FlutterLayerContentType type) {
|
|
switch (type) {
|
|
case kFlutterLayerContentTypeBackingStore:
|
|
return "kFlutterLayerContentTypeBackingStore";
|
|
case kFlutterLayerContentTypePlatformView:
|
|
return "kFlutterLayerContentTypePlatformView";
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
inline std::string FlutterBackingStoreTypeToString(
|
|
FlutterBackingStoreType type) {
|
|
switch (type) {
|
|
case kFlutterBackingStoreTypeOpenGL:
|
|
return "kFlutterBackingStoreTypeOpenGL";
|
|
case kFlutterBackingStoreTypeSoftware:
|
|
return "kFlutterBackingStoreTypeSoftware";
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterOpenGLTexture& item) {
|
|
return out << "(FlutterOpenGLTexture) Target: 0x" << std::hex << item.target
|
|
<< std::dec << " Name: " << item.name << " Format: " << item.format
|
|
<< " User Data: " << item.user_data << " Destruction Callback: "
|
|
<< reinterpret_cast<void*>(item.destruction_callback);
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterOpenGLFramebuffer& item) {
|
|
return out << "(FlutterOpenGLFramebuffer) Target: 0x" << std::hex
|
|
<< item.target << std::dec << " Name: " << item.name
|
|
<< " User Data: " << item.user_data << " Destruction Callback: "
|
|
<< reinterpret_cast<void*>(item.destruction_callback);
|
|
}
|
|
|
|
inline std::string FlutterPlatformViewMutationTypeToString(
|
|
FlutterPlatformViewMutationType type) {
|
|
switch (type) {
|
|
case kFlutterPlatformViewMutationTypeOpacity:
|
|
return "kFlutterPlatformViewMutationTypeOpacity";
|
|
case kFlutterPlatformViewMutationTypeClipRect:
|
|
return "kFlutterPlatformViewMutationTypeClipRect";
|
|
case kFlutterPlatformViewMutationTypeClipRoundedRect:
|
|
return "kFlutterPlatformViewMutationTypeClipRoundedRect";
|
|
case kFlutterPlatformViewMutationTypeTransformation:
|
|
return "kFlutterPlatformViewMutationTypeTransformation";
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterPlatformViewMutation& m) {
|
|
out << "(FlutterPlatformViewMutation) Type: "
|
|
<< FlutterPlatformViewMutationTypeToString(m.type) << " ";
|
|
switch (m.type) {
|
|
case kFlutterPlatformViewMutationTypeOpacity:
|
|
out << "Opacity: " << m.opacity;
|
|
case kFlutterPlatformViewMutationTypeClipRect:
|
|
out << "Clip Rect: " << m.clip_rect;
|
|
case kFlutterPlatformViewMutationTypeClipRoundedRect:
|
|
out << "Clip Rounded Rect: " << m.clip_rounded_rect;
|
|
case kFlutterPlatformViewMutationTypeTransformation:
|
|
out << "Transformation: " << m.transformation;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterPlatformView& platform_view) {
|
|
out << "["
|
|
<< "(FlutterPlatformView) Struct Size: " << platform_view.struct_size
|
|
<< " Identifier: " << platform_view.identifier
|
|
<< " Mutations Count: " << platform_view.mutations_count;
|
|
|
|
if (platform_view.mutations_count > 0) {
|
|
out << std::endl;
|
|
for (size_t i = 0; i < platform_view.mutations_count; i++) {
|
|
out << "Mutation " << i << ": " << *platform_view.mutations[i]
|
|
<< std::endl;
|
|
}
|
|
}
|
|
|
|
out << "]";
|
|
|
|
return out;
|
|
}
|
|
|
|
inline std::string FlutterOpenGLTargetTypeToString(
|
|
FlutterOpenGLTargetType type) {
|
|
switch (type) {
|
|
case kFlutterOpenGLTargetTypeTexture:
|
|
return "kFlutterOpenGLTargetTypeTexture";
|
|
case kFlutterOpenGLTargetTypeFramebuffer:
|
|
return "kFlutterOpenGLTargetTypeFramebuffer";
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterOpenGLBackingStore& item) {
|
|
out << "(FlutterOpenGLBackingStore) Type: "
|
|
<< FlutterOpenGLTargetTypeToString(item.type) << " ";
|
|
switch (item.type) {
|
|
case kFlutterOpenGLTargetTypeTexture:
|
|
out << item.texture;
|
|
break;
|
|
case kFlutterOpenGLTargetTypeFramebuffer:
|
|
out << item.framebuffer;
|
|
break;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterSoftwareBackingStore& item) {
|
|
return out << "(FlutterSoftwareBackingStore) Allocation: " << item.allocation
|
|
<< " Row Bytes: " << item.row_bytes << " Height: " << item.height
|
|
<< " User Data: " << item.user_data << " Destruction Callback: "
|
|
<< reinterpret_cast<void*>(item.destruction_callback);
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out,
|
|
const FlutterBackingStore& backing_store) {
|
|
out << "(FlutterBackingStore) Struct size: " << backing_store.struct_size
|
|
<< " User Data: " << backing_store.user_data
|
|
<< " Type: " << FlutterBackingStoreTypeToString(backing_store.type)
|
|
<< " ";
|
|
|
|
switch (backing_store.type) {
|
|
case kFlutterBackingStoreTypeOpenGL:
|
|
out << backing_store.open_gl;
|
|
break;
|
|
|
|
case kFlutterBackingStoreTypeSoftware:
|
|
out << backing_store.software;
|
|
break;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, const FlutterLayer& layer) {
|
|
out << "(Flutter Layer) Struct size: " << layer.struct_size
|
|
<< " Type: " << FlutterLayerContentTypeToString(layer.type);
|
|
|
|
switch (layer.type) {
|
|
case kFlutterLayerContentTypeBackingStore:
|
|
out << *layer.backing_store;
|
|
break;
|
|
case kFlutterLayerContentTypePlatformView:
|
|
out << *layer.platform_view;
|
|
break;
|
|
}
|
|
|
|
return out << " Offset: " << layer.offset << " Size: " << layer.size;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Factories and Casts
|
|
//------------------------------------------------------------------------------
|
|
|
|
inline FlutterPoint FlutterPointMake(double x, double y) {
|
|
FlutterPoint point = {};
|
|
point.x = x;
|
|
point.y = y;
|
|
return point;
|
|
}
|
|
|
|
inline FlutterSize FlutterSizeMake(double width, double height) {
|
|
FlutterSize size = {};
|
|
size.width = width;
|
|
size.height = height;
|
|
return size;
|
|
}
|
|
|
|
inline FlutterSize FlutterSizeMake(const SkVector& vector) {
|
|
FlutterSize size = {};
|
|
size.width = vector.x();
|
|
size.height = vector.y();
|
|
return size;
|
|
}
|
|
|
|
inline FlutterTransformation FlutterTransformationMake(const SkMatrix& matrix) {
|
|
FlutterTransformation transformation = {};
|
|
transformation.scaleX = matrix[SkMatrix::kMScaleX];
|
|
transformation.skewX = matrix[SkMatrix::kMSkewX];
|
|
transformation.transX = matrix[SkMatrix::kMTransX];
|
|
transformation.skewY = matrix[SkMatrix::kMSkewY];
|
|
transformation.scaleY = matrix[SkMatrix::kMScaleY];
|
|
transformation.transY = matrix[SkMatrix::kMTransY];
|
|
transformation.pers0 = matrix[SkMatrix::kMPersp0];
|
|
transformation.pers1 = matrix[SkMatrix::kMPersp1];
|
|
transformation.pers2 = matrix[SkMatrix::kMPersp2];
|
|
return transformation;
|
|
}
|
|
|
|
inline SkMatrix SkMatrixMake(const FlutterTransformation& xformation) {
|
|
return SkMatrix::MakeAll(xformation.scaleX, //
|
|
xformation.skewX, //
|
|
xformation.transX, //
|
|
xformation.skewY, //
|
|
xformation.scaleY, //
|
|
xformation.transY, //
|
|
xformation.pers0, //
|
|
xformation.pers1, //
|
|
xformation.pers2 //
|
|
);
|
|
}
|
|
|
|
inline flutter::EmbedderEngine* ToEmbedderEngine(const FlutterEngine& engine) {
|
|
return reinterpret_cast<flutter::EmbedderEngine*>(engine);
|
|
}
|
|
|
|
inline FlutterRect FlutterRectMake(const SkRect& rect) {
|
|
FlutterRect r = {};
|
|
r.left = rect.left();
|
|
r.top = rect.top();
|
|
r.right = rect.right();
|
|
r.bottom = rect.bottom();
|
|
return r;
|
|
}
|
|
|
|
inline FlutterRect FlutterRectMakeLTRB(double l, double t, double r, double b) {
|
|
FlutterRect rect = {};
|
|
rect.left = l;
|
|
rect.top = t;
|
|
rect.right = r;
|
|
rect.bottom = b;
|
|
return rect;
|
|
}
|
|
|
|
inline SkRect SkRectMake(const FlutterRect& rect) {
|
|
return SkRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom);
|
|
}
|
|
|
|
inline FlutterRoundedRect FlutterRoundedRectMake(const SkRRect& rect) {
|
|
FlutterRoundedRect r = {};
|
|
r.rect = FlutterRectMake(rect.rect());
|
|
r.upper_left_corner_radius =
|
|
FlutterSizeMake(rect.radii(SkRRect::Corner::kUpperLeft_Corner));
|
|
r.upper_right_corner_radius =
|
|
FlutterSizeMake(rect.radii(SkRRect::Corner::kUpperRight_Corner));
|
|
r.lower_right_corner_radius =
|
|
FlutterSizeMake(rect.radii(SkRRect::Corner::kLowerRight_Corner));
|
|
r.lower_left_corner_radius =
|
|
FlutterSizeMake(rect.radii(SkRRect::Corner::kLowerLeft_Corner));
|
|
return r;
|
|
}
|
|
|
|
#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_ASSERTIONS_H_
|