blob: 9c1faea3bc6492632e43a41b58ac1baa8cdb1647 [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.
#include "fake_flatland_types.h"
#include <lib/fidl/cpp/clone.h>
#include <lib/zx/channel.h>
#include <lib/zx/eventpair.h>
#include "flutter/fml/logging.h"
namespace flutter_runner::testing {
namespace {
using FakeTransformCache =
std::unordered_map<const FakeTransform*, std::shared_ptr<FakeTransform>>;
std::vector<std::shared_ptr<FakeTransform>> CloneFakeTransformVector(
const std::vector<std::shared_ptr<FakeTransform>>& transforms,
FakeTransformCache& transform_cache);
std::shared_ptr<FakeContent> CloneFakeContent(
const std::shared_ptr<FakeContent>& content) {
if (content == nullptr) {
return nullptr;
}
if (FakeViewport* viewport = std::get_if<FakeViewport>(content.get())) {
return std::make_shared<FakeContent>(FakeViewport{
.id = viewport->id,
.viewport_properties = fidl::Clone(viewport->viewport_properties),
.viewport_token = viewport->viewport_token,
.child_view_watcher = viewport->child_view_watcher,
});
} else if (FakeImage* image = std::get_if<FakeImage>(content.get())) {
return std::make_shared<FakeContent>(FakeImage{
.id = image->id,
.image_properties = fidl::Clone(image->image_properties),
.sample_region = image->sample_region,
.destination_size = image->destination_size,
.opacity = image->opacity,
.blend_mode = image->blend_mode,
.import_token = image->import_token,
.vmo_index = image->vmo_index,
});
} else {
FML_UNREACHABLE();
}
}
std::shared_ptr<FakeTransform> CloneFakeTransform(
const std::shared_ptr<FakeTransform>& transform,
FakeTransformCache& transform_cache) {
if (transform == nullptr) {
return nullptr;
}
auto found_transform = transform_cache.find(transform.get());
if (found_transform != transform_cache.end()) {
return found_transform->second;
}
auto [emplaced_transform, success] = transform_cache.emplace(
transform.get(), std::make_shared<FakeTransform>(FakeTransform{
.id = transform->id,
.translation = transform->translation,
.clip_bounds = transform->clip_bounds,
.orientation = transform->orientation,
.children = CloneFakeTransformVector(
transform->children, transform_cache),
.content = CloneFakeContent(transform->content),
}));
FML_CHECK(success);
return emplaced_transform->second;
}
std::vector<std::shared_ptr<FakeTransform>> CloneFakeTransformVector(
const std::vector<std::shared_ptr<FakeTransform>>& transforms,
FakeTransformCache& transform_cache) {
std::vector<std::shared_ptr<FakeTransform>> clones;
for (auto& transform : transforms) {
clones.emplace_back(CloneFakeTransform(transform, transform_cache));
}
return clones;
}
} // namespace
ViewTokenPair ViewTokenPair::New() {
ViewTokenPair token_pair;
auto status = zx::channel::create(0u, &token_pair.view_token.value,
&token_pair.viewport_token.value);
FML_CHECK(status == ZX_OK);
return token_pair;
}
BufferCollectionTokenPair BufferCollectionTokenPair::New() {
BufferCollectionTokenPair token_pair;
auto status = zx::eventpair::create(0u, &token_pair.export_token.value,
&token_pair.import_token.value);
FML_CHECK(status == ZX_OK);
return token_pair;
}
bool FakeView::operator==(const FakeView& other) const {
return view_token == other.view_token && view_ref == other.view_ref &&
view_ref_control == other.view_ref_control &&
view_ref_focused == other.view_ref_focused &&
focuser == other.focuser && touch_source == other.touch_source &&
mouse_source == other.mouse_source &&
parent_viewport_watcher == other.parent_viewport_watcher;
}
bool FakeViewport::operator==(const FakeViewport& other) const {
return id == other.id && viewport_properties == other.viewport_properties &&
viewport_token == other.viewport_token &&
child_view_watcher == other.child_view_watcher;
}
bool FakeImage::operator==(const FakeImage& other) const {
return id == other.id && image_properties == other.image_properties &&
sample_region == other.sample_region &&
destination_size == other.destination_size &&
opacity == other.opacity && blend_mode == other.blend_mode &&
import_token == other.import_token && vmo_index == other.vmo_index;
}
bool FakeTransform::operator==(const FakeTransform& other) const {
return id == other.id && translation == other.translation &&
clip_bounds == other.clip_bounds && orientation == other.orientation &&
children == other.children && content == other.content;
}
bool FakeGraph::operator==(const FakeGraph& other) const {
return transform_map == other.transform_map &&
content_map == other.content_map &&
root_transform == other.root_transform && view == other.view;
}
void FakeGraph::Clear() {
view.reset();
root_transform.reset();
transform_map.clear();
content_map.clear();
}
FakeGraph FakeGraph::Clone() const {
FakeGraph clone;
FakeTransformCache transform_cache;
for (const auto& [transform_id, transform] : transform_map) {
FML_CHECK(transform);
clone.transform_map.emplace(transform_id,
CloneFakeTransform(transform, transform_cache));
}
for (const auto& [content_id, content] : content_map) {
FML_CHECK(content);
clone.content_map.emplace(content_id, CloneFakeContent(content));
}
if (root_transform) {
auto found_transform = transform_cache.find(root_transform.get());
FML_CHECK(found_transform != transform_cache.end());
clone.root_transform = found_transform->second;
}
if (view.has_value()) {
clone.view.emplace(view.value());
}
return clone;
}
} // namespace flutter_runner::testing