blob: 72c15d0180aebcff75a8d7d18f4d7ff034dadd2f [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 "src/ui/lib/escher/paper/paper_transform_stack.h"
#include "src/ui/lib/escher/geometry/plane_ops.h"
#include "src/ui/lib/escher/util/trace_macros.h"
namespace escher {
PaperTransformStack::PaperTransformStack() = default;
const PaperTransformStack::Item& PaperTransformStack::PushTransform(const mat4& transform) {
TRACE_DURATION("gfx.debug", "PaperTransformStack::PushTransform", "stack_size", size(),
"num_clip_planes", num_clip_planes());
const auto& cur = Top();
Item item;
item.clip_planes.reserve(cur.clip_planes.size());
for (auto& plane : cur.clip_planes) {
item.clip_planes.push_back(TransformPlane(transform, plane));
}
item.matrix = cur.matrix * transform;
stack_.push(std::move(item));
return stack_.top();
}
const PaperTransformStack::Item& PaperTransformStack::PushTranslation(const vec3& translation) {
TRACE_DURATION("gfx", "PaperTransformStack::PushTranslation", "stack_size", size(),
"num_clip_planes", num_clip_planes());
const auto& cur = Top();
Item item;
item.clip_planes.reserve(cur.clip_planes.size());
for (auto& plane : cur.clip_planes) {
item.clip_planes.push_back(TranslatePlane(translation, plane));
}
item.matrix = glm::translate(cur.matrix, translation);
stack_.push(std::move(item));
return stack_.top();
}
const PaperTransformStack::Item& PaperTransformStack::PushScale(float scale) {
TRACE_DURATION("gfx", "PaperTransformStack::PushScale", "stack_size", size(), "num_clip_planes",
num_clip_planes());
const auto& cur = Top();
Item item;
item.clip_planes.reserve(cur.clip_planes.size());
for (auto& plane : cur.clip_planes) {
item.clip_planes.push_back(ScalePlane(scale, plane));
}
item.matrix = glm::scale(cur.matrix, vec3(scale, scale, scale));
stack_.push(std::move(item));
return stack_.top();
}
const PaperTransformStack::Item& PaperTransformStack::PushIdentity() {
stack_.push(Top());
return stack_.top();
}
const PaperTransformStack::Item& PaperTransformStack::AddClipPlanes(const plane3* clip_planes,
size_t num_clip_planes) {
FX_DCHECK(clip_planes || num_clip_planes == 0);
if (!clip_planes) {
return Top();
} else if (stack_.empty()) {
PushIdentity();
}
auto& cur = stack_.top();
cur.clip_planes.reserve(cur.clip_planes.size() + num_clip_planes);
for (size_t i = 0; i < num_clip_planes; ++i) {
cur.clip_planes.push_back(clip_planes[i]);
}
return cur;
}
PaperTransformStack& PaperTransformStack::Pop() {
if (!empty()) {
stack_.pop();
}
return *this;
}
PaperTransformStack& PaperTransformStack::Clear(
std::pair<size_t, size_t> stack_size_and_num_clip_planes) {
auto [target_stack_size, target_num_clip_planes] = stack_size_and_num_clip_planes;
FX_DCHECK(stack_.size() >= target_stack_size);
while (stack_.size() > target_stack_size) {
stack_.pop();
}
if (stack_.empty()) {
FX_DCHECK(target_num_clip_planes == 0);
} else {
auto& clip_planes = stack_.top().clip_planes;
FX_DCHECK(target_num_clip_planes <= clip_planes.size())
<< "stack currently has " << clip_planes.size()
<< " clip-planes, which is fewer than the target: " << target_num_clip_planes << ".";
clip_planes.resize(target_num_clip_planes);
}
return *this;
}
} // namespace escher