blob: 29737411c0740e77e478f31352c654c4214179e9 [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 "impeller/aiks/picture.h"
#include <memory>
#include <optional>
#include "impeller/base/validation.h"
#include "impeller/entity/entity.h"
#include "impeller/renderer/render_target.h"
#include "impeller/renderer/snapshot.h"
namespace impeller {
std::optional<Snapshot> Picture::Snapshot(AiksContext& context) {
auto coverage = pass->GetElementsCoverage(std::nullopt);
if (!coverage.has_value() || coverage->IsEmpty()) {
return std::nullopt;
}
const auto translate = Matrix::MakeTranslation(-coverage.value().origin);
auto texture =
RenderToTexture(context, ISize(coverage.value().size), translate);
return impeller::Snapshot{
.texture = std::move(texture),
.transform = Matrix::MakeTranslation(coverage.value().origin)};
}
std::shared_ptr<Image> Picture::ToImage(AiksContext& context, ISize size) {
if (size.IsEmpty()) {
return nullptr;
}
auto texture = RenderToTexture(context, size);
return texture ? std::make_shared<Image>(texture) : nullptr;
}
std::shared_ptr<Texture> Picture::RenderToTexture(
AiksContext& context,
ISize size,
std::optional<const Matrix> translate) {
FML_DCHECK(!size.IsEmpty());
pass->IterateAllEntities([&translate](auto& entity) -> bool {
auto matrix = translate.has_value()
? translate.value() * entity.GetTransformation()
: entity.GetTransformation();
entity.SetTransformation(matrix);
return true;
});
// This texture isn't host visible, but we might want to add host visible
// features to Image someday.
auto impeller_context = context.GetContext();
RenderTarget target;
if (impeller_context->SupportsOffscreenMSAA()) {
target = RenderTarget::CreateOffscreenMSAA(*impeller_context, size);
} else {
target = RenderTarget::CreateOffscreen(*impeller_context, size);
}
if (!target.IsValid()) {
VALIDATION_LOG << "Could not create valid RenderTarget.";
return nullptr;
}
if (!context.Render(*this, target)) {
VALIDATION_LOG << "Could not render Picture to Texture.";
return nullptr;
}
auto texture = target.GetRenderTargetTexture();
if (!texture) {
VALIDATION_LOG << "RenderTarget has no target texture.";
return nullptr;
}
return texture;
}
} // namespace impeller