blob: ea60725e9cb481600f8923259e2c91b949a7bf4b [file] [log] [blame]
// 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_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_RESOURCES_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_RESOURCES_H_
#include <fuchsia/images/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>
#include <array>
#include <memory>
#include <string>
#include <unordered_map>
#include <variant>
#include <vector>
inline bool operator==(const fuchsia::images::ImageInfo& a,
const fuchsia::images::ImageInfo& b) {
return a.height == b.height && a.width == b.width && a.stride == b.stride &&
a.tiling == b.tiling && a.transform == b.transform &&
a.alpha_format == b.alpha_format && a.pixel_format == b.pixel_format &&
a.color_space == b.color_space;
}
inline bool operator==(const fuchsia::ui::gfx::vec3& a,
const fuchsia::ui::gfx::vec3& b) {
return a.x == b.x && a.y == b.y && a.z == b.z;
}
inline bool operator==(const fuchsia::ui::gfx::BoundingBox& a,
const fuchsia::ui::gfx::BoundingBox& b) {
return a.min == b.min && a.max == b.max;
}
inline bool operator==(const fuchsia::ui::gfx::ViewProperties& a,
const fuchsia::ui::gfx::ViewProperties& b) {
return a.downward_input == b.downward_input &&
a.focus_change == b.focus_change && a.bounding_box == b.bounding_box &&
a.inset_from_min == b.inset_from_min &&
a.inset_from_max == b.inset_from_max;
}
namespace flutter_runner::testing {
// Forward declarations
template <typename S>
struct FakeResourceT;
// Unique (within a Session) identifier for a Resource.
using FakeResourceId = decltype(fuchsia::ui::gfx::CreateResourceCmd::id);
constexpr FakeResourceId kInvalidFakeResourceId = 0u;
// Tag type for a Resource "state". The Resource state keeps alive any handles
// associated with a resource e.g. view token or sysmem token.
//
// "snapshot" Resources are generated from "state" Resources during
// `SceneGraphFromState()` calls.
//
// The `FakeSession` stores `FakeResourceT<StateT>` internally.
struct StateT {
using ResourceT = FakeResourceT<StateT>;
template <typename T>
struct HandleT {
T value{};
zx_koid_t koid{ZX_KOID_INVALID};
};
template <typename T>
static bool HandlesAreEqual(const HandleT<T>& token,
const HandleT<T>& other_token) {
return token.koid == other_token.koid;
}
};
// Tag type for a Resource "snapshot". The Resource snapshot only stores koids
// for any handles associated with the resource; in this way it doesn't have any
// control over the underlying handle lifetime.
//
// "snapshot" Resources are generated from "state" Resources during
// `SceneGraphFromState()` calls.
//
// The `FakeSession` returns `FakeResourceT<SnapshotT>` from its `SceneGraph()`
// accessor.
struct SnapshotT {
using ResourceT = FakeResourceT<SnapshotT>;
template <typename T>
using HandleT = zx_koid_t;
template <typename T>
static bool HandlesAreEqual(const HandleT<T>& token,
const HandleT<T>& other_token) {
return token == other_token;
}
};
// Common state for Node-typed Resources: EntityNode, OpacityNode, ShapeNode,
// ViewHolder.
//
// FakeNodeT's are never used directly, only as an embedded field of a
// Node-typed resource.
template <typename S>
struct FakeNodeT {
bool operator==(const FakeNodeT& other) const;
constexpr static std::array<float, 4> kDefaultZeroRotation{0.f, 0.f, 0.f,
1.f};
constexpr static std::array<float, 3> kDefaultOneScale{1.f, 1.f, 1.f};
constexpr static std::array<float, 3> kDefaultZeroTranslation{0.f, 0.f, 0.f};
constexpr static std::array<float, 3> kDefaultZeroAnchor{0.f, 0.f, 0.f};
constexpr static bool kIsHitTestable{true};
constexpr static bool kIsNotHitTestable{false};
constexpr static bool kIsSemanticallyVisible{true};
constexpr static bool kIsNotSemanticallyVisible{false};
std::vector<std::shared_ptr<typename S::ResourceT>> children;
std::array<float, 4> rotation_quaternion{kDefaultZeroRotation};
std::array<float, 3> scale_vector{kDefaultOneScale};
std::array<float, 3> translation_vector{kDefaultZeroTranslation};
std::array<float, 3> anchor_vector{kDefaultZeroAnchor};
bool hit_testable{kIsHitTestable};
bool semantically_visible{kIsSemanticallyVisible};
};
using FakeNodeState = FakeNodeT<StateT>;
using FakeNode = FakeNodeT<SnapshotT>;
// EntityNode Resource state.
template <typename S>
struct FakeEntityNodeT {
struct ClipPlane {
bool operator==(const ClipPlane& other) const;
constexpr static std::array<float, 3> kDefaultZeroDir{0.f, 0.f, 0.f};
constexpr static float kDefaultZeroDist{0.f};
std::array<float, 3> dir{kDefaultZeroDir};
float dist{kDefaultZeroDist};
};
bool operator==(const FakeEntityNodeT& other) const;
FakeNodeT<S> node_state;
std::vector<ClipPlane> clip_planes;
};
using FakeEntityNodeState = FakeEntityNodeT<StateT>;
using FakeEntityNode = FakeEntityNodeT<SnapshotT>;
// OpacityNode Resource state.
template <typename S>
struct FakeOpacityNodeT {
bool operator==(const FakeOpacityNodeT& other) const;
FakeNodeT<S> node_state;
constexpr static float kDefaultOneOpacity{1.f};
float opacity{kDefaultOneOpacity};
};
using FakeOpacityNodeState = FakeOpacityNodeT<StateT>;
using FakeOpacityNode = FakeOpacityNodeT<SnapshotT>;
// ShapeNode Resource state.
template <typename S>
struct FakeShapeNodeT {
bool operator==(const FakeShapeNodeT& other) const;
FakeNodeT<S> node_state;
std::shared_ptr<typename S::ResourceT> shape;
std::shared_ptr<typename S::ResourceT> material;
};
using FakeShapeNodeState = FakeShapeNodeT<StateT>;
using FakeShapeNode = FakeShapeNodeT<SnapshotT>;
// View Resource state.
template <typename S>
struct FakeViewT {
bool operator==(const FakeViewT& other) const;
constexpr static bool kDebugBoundsEnabled{true};
constexpr static bool kDebugBoundsDisbaled{false};
typename S::template HandleT<fuchsia::ui::views::ViewToken> token{};
typename S::template HandleT<fuchsia::ui::views::ViewRefControl>
control_ref{};
typename S::template HandleT<fuchsia::ui::views::ViewRef> view_ref{};
std::string debug_name{};
std::vector<std::shared_ptr<typename S::ResourceT>> children;
bool enable_debug_bounds{kDebugBoundsDisbaled};
};
using FakeViewState = FakeViewT<StateT>;
using FakeView = FakeViewT<SnapshotT>;
// ViewHolder Resource state.
template <typename S>
struct FakeViewHolderT {
bool operator==(const FakeViewHolderT& other) const;
FakeNodeT<S> node_state;
constexpr static std::array<float, 4> kDefaultBoundsColorWhite{1.f, 1.f, 1.f,
1.f};
typename S::template HandleT<fuchsia::ui::views::ViewHolderToken> token{};
std::string debug_name{};
fuchsia::ui::gfx::ViewProperties properties;
std::array<float, 4> bounds_color{kDefaultBoundsColorWhite};
};
using FakeViewHolderState = FakeViewHolderT<StateT>;
using FakeViewHolder = FakeViewHolderT<SnapshotT>;
// Shape Resource state.
template <typename S>
struct FakeShapeT {
bool operator==(const FakeShapeT& other) const;
struct CircleDef {
bool operator==(const CircleDef& other) const;
float radius{0.f};
};
struct RectangleDef {
bool operator==(const RectangleDef& other) const;
float width{0.f};
float height{0.f};
};
struct RoundedRectangleDef {
bool operator==(const RoundedRectangleDef& other) const;
float width{0.f};
float height{0.f};
float top_left_radius{0.f};
float top_right_radius{0.f};
float bottom_right_radius{0.f};
float bottom_left_radius{0.f};
};
std::variant<CircleDef, RectangleDef, RoundedRectangleDef> shape_def;
};
using FakeShapeState = FakeShapeT<StateT>;
using FakeShape = FakeShapeT<SnapshotT>;
// Material Resource state.
template <typename S>
struct FakeMaterialT {
bool operator==(const FakeMaterialT& other) const;
constexpr static std::array<float, 4> kDefaultColorWhite{1.f, 1.f, 1.f, 1.f};
std::shared_ptr<typename S::ResourceT> image;
std::array<float, 4> color{kDefaultColorWhite};
};
using FakeMaterialState = FakeMaterialT<StateT>;
using FakeMaterial = FakeMaterialT<SnapshotT>;
// Image Resource state.
template <typename S>
struct FakeImageT {
struct ImageDef {
bool operator==(const ImageDef& other) const;
fuchsia::images::ImageInfo info{};
uint32_t memory_offset{};
};
struct Image2Def {
bool operator==(const Image2Def& other) const;
uint32_t buffer_collection_id{};
uint32_t buffer_collection_index{};
uint32_t width{};
uint32_t height{};
};
struct Image3Def {
bool operator==(const Image3Def& other) const;
typename S::template HandleT<
fuchsia::ui::composition::BufferCollectionImportToken>
import_token{};
uint32_t buffer_collection_index{};
uint32_t width{};
uint32_t height{};
};
struct ImagePipeDef {
bool operator==(const ImagePipeDef& other) const;
typename S::template HandleT<
fidl::InterfaceRequest<fuchsia::images::ImagePipe>>
image_pipe_request{};
};
struct ImagePipe2Def {
bool operator==(const ImagePipe2Def& other) const;
typename S::template HandleT<
fidl::InterfaceRequest<fuchsia::images::ImagePipe2>>
image_pipe_request{};
};
bool operator==(const FakeImageT& other) const;
std::variant<ImageDef, Image2Def, Image3Def, ImagePipeDef, ImagePipe2Def>
image_def;
std::shared_ptr<typename S::ResourceT> memory;
};
using FakeImageState = FakeImageT<StateT>;
using FakeImage = FakeImageT<SnapshotT>;
// Memory Resource state.
template <typename S>
struct FakeMemoryT {
bool operator==(const FakeMemoryT& other) const;
constexpr static bool kIsDeviceMemory{true};
constexpr static bool kIsNotDeviceMemory{false};
typename S::template HandleT<zx::vmo> vmo{};
uint64_t allocation_size{};
bool is_device_memory{kIsNotDeviceMemory};
};
using FakeMemoryState = FakeMemoryT<StateT>;
using FakeMemory = FakeMemoryT<SnapshotT>;
// A complete Resource which records common Resource data and stores it's
// type-specific state inside of a variant.
template <typename S>
struct FakeResourceT {
bool operator==(const FakeResourceT& other) const;
constexpr static uint32_t kDefaultEmptyEventMask{0};
FakeResourceId id{kInvalidFakeResourceId};
std::string label{};
uint32_t event_mask{kDefaultEmptyEventMask};
std::variant<FakeEntityNodeT<S>,
FakeOpacityNodeT<S>,
FakeShapeNodeT<S>,
FakeViewT<S>,
FakeViewHolderT<S>,
FakeShapeT<S>,
FakeMaterialT<S>,
FakeImageT<S>,
FakeMemoryT<S>>
state;
};
using FakeResourceState = FakeResourceT<StateT>;
using FakeResource = FakeResourceT<SnapshotT>;
// A complete scene graph which records a forest of Resource trees.
//
// It also records auxiliary data like buffer collection IDs and resource labels
// for fast lookup.
//
// Each Session / scene graph may only have a single View Resource which is
// treated as the root of that scene. The root View and all Resources
// descending from it are what the real scenic implementation would submit for
// rendering.
template <typename S>
struct FakeSceneGraphT {
bool operator==(const FakeSceneGraphT& other) const;
std::unordered_map<uint32_t,
typename S::template HandleT<fidl::InterfaceHandle<
fuchsia::sysmem::BufferCollectionToken>>>
buffer_collection_map;
std::unordered_map<FakeResourceId, std::shared_ptr<FakeResourceT<S>>>
resource_map;
std::unordered_map<std::string, std::vector<std::weak_ptr<FakeResourceT<S>>>>
label_map;
FakeResourceId root_view_id{kInvalidFakeResourceId};
};
using FakeSceneGraphState = FakeSceneGraphT<StateT>;
using FakeSceneGraph = FakeSceneGraphT<SnapshotT>;
// Generate a snapshot of a scene graph from that scene graph's state.
//
// The lifetime of the snapshot and its Resources has no influence on the
// lifetime of the source scene graph or its Resources.
FakeSceneGraph SceneGraphFromState(const FakeSceneGraphState& state);
template <typename S>
bool FakeEntityNodeT<S>::ClipPlane::operator==(
const FakeEntityNodeT<S>::ClipPlane& other) const {
return dir == other.dir && dist == other.dist;
}
template <typename S>
bool FakeNodeT<S>::operator==(const FakeNodeT<S>& other) const {
return children == other.children &&
rotation_quaternion == other.rotation_quaternion &&
scale_vector == other.scale_vector &&
translation_vector == other.translation_vector &&
anchor_vector == other.anchor_vector &&
hit_testable == other.hit_testable &&
semantically_visible == other.semantically_visible;
}
template <typename S>
bool FakeEntityNodeT<S>::operator==(const FakeEntityNodeT<S>& other) const {
return node_state == other.node_state && clip_planes == other.clip_planes;
}
template <typename S>
bool FakeOpacityNodeT<S>::operator==(const FakeOpacityNodeT<S>& other) const {
return node_state == other.node_state && opacity == other.opacity;
}
template <typename S>
bool FakeShapeNodeT<S>::operator==(const FakeShapeNodeT<S>& other) const {
return node_state == other.node_state && shape == other.shape &&
material == other.material;
}
template <typename S>
bool FakeViewT<S>::operator==(const FakeViewT<S>& other) const {
return S::template HandlesAreEqual<fuchsia::ui::views::ViewToken>(
token, other.token) &&
S::template HandlesAreEqual<fuchsia::ui::views::ViewRefControl>(
control_ref, other.control_ref) &&
S::template HandlesAreEqual<fuchsia::ui::views::ViewRef>(
view_ref, other.view_ref) &&
children == other.children && debug_name == other.debug_name &&
enable_debug_bounds == other.enable_debug_bounds;
}
template <typename S>
bool FakeViewHolderT<S>::operator==(const FakeViewHolderT<S>& other) const {
return FakeNodeT<S>::operator==(other) &&
S::template HandlesAreEqual<fuchsia::ui::views::ViewHolderToken>(
token, other.token) &&
debug_name == other.debug_name && properties == other.properties &&
bounds_color == other.bounds_color;
}
template <typename S>
bool FakeShapeT<S>::CircleDef::operator==(
const FakeShapeT<S>::CircleDef& other) const {
return radius == other.radius;
}
template <typename S>
bool FakeShapeT<S>::RectangleDef::operator==(
const FakeShapeT<S>::RectangleDef& other) const {
return width == other.width && height == other.height;
}
template <typename S>
bool FakeShapeT<S>::RoundedRectangleDef::operator==(
const FakeShapeT<S>::RoundedRectangleDef& other) const {
return width == other.width && height == other.height &&
top_left_radius == other.top_left_radius &&
top_right_radius == other.top_right_radius &&
bottom_right_radius == other.bottom_right_radius &&
bottom_left_radius == other.bottom_left_radius;
}
template <typename S>
bool FakeShapeT<S>::operator==(const FakeShapeT<S>& other) const {
return shape_def == other.shape_def;
}
template <typename S>
bool FakeMaterialT<S>::operator==(const FakeMaterialT<S>& other) const {
return image == other.image && color == other.color;
}
template <typename S>
bool FakeImageT<S>::ImageDef::operator==(
const FakeImageT<S>::ImageDef& other) const {
return info == other.info && memory_offset == other.memory_offset;
}
template <typename S>
bool FakeImageT<S>::Image2Def::operator==(
const FakeImageT<S>::Image2Def& other) const {
return buffer_collection_id == other.buffer_collection_id &&
buffer_collection_index == other.buffer_collection_index &&
width == other.width && height == other.height;
}
template <typename S>
bool FakeImageT<S>::Image3Def::operator==(
const FakeImageT<S>::Image3Def& other) const {
return S::template HandlesAreEqual<
fuchsia::ui::composition::BufferCollectionImportToken>(
import_token, other.import_token) &&
buffer_collection_index == other.buffer_collection_index &&
width == other.width && height == other.height;
}
template <typename S>
bool FakeImageT<S>::ImagePipeDef::operator==(
const FakeImageT<S>::ImagePipeDef& other) const {
return S::template HandlesAreEqual<
fidl::InterfaceRequest<fuchsia::images::ImagePipe>>(
image_pipe_request, other.image_pipe_request);
}
template <typename S>
bool FakeImageT<S>::ImagePipe2Def::operator==(
const FakeImageT<S>::ImagePipe2Def& other) const {
return S::template HandlesAreEqual<
fidl::InterfaceRequest<fuchsia::images::ImagePipe2>>(
image_pipe_request, other.image_pipe_request);
}
template <typename S>
bool FakeImageT<S>::operator==(const FakeImageT<S>& other) const {
return image_def == other.image_def && memory == other.memory;
}
template <typename S>
bool FakeMemoryT<S>::operator==(const FakeMemoryT<S>& other) const {
return S::template HandlesAreEqual<zx::vmo>(vmo, other.vmo) &&
allocation_size == other.allocation_size &&
is_device_memory == other.is_device_memory;
}
template <typename S>
bool FakeResourceT<S>::operator==(const FakeResourceT<S>& other) const {
return id == other.id && label == other.label &&
event_mask == other.event_mask && state == other.state;
}
template <typename S>
bool FakeSceneGraphT<S>::operator==(const FakeSceneGraphT<S>& other) const {
return buffer_collection_map == other.buffer_collection_map &&
resource_map ==
other.resource_map && // labels_map == other.labels_map &&
root_view_id == other.root_view_id;
}
} // namespace flutter_runner::testing
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_RESOURCES_H_