blob: dd53e125645b5dc96a71a09493ac9b49bf8dad54 [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/renderer/blit_pass.h"
#include <memory>
#include <utility>
#include "impeller/base/strings.h"
#include "impeller/base/validation.h"
#include "impeller/renderer/blit_command.h"
#include "impeller/renderer/host_buffer.h"
namespace impeller {
BlitPass::BlitPass() : transients_buffer_(HostBuffer::Create()) {}
BlitPass::~BlitPass() = default;
HostBuffer& BlitPass::GetTransientsBuffer() {
return *transients_buffer_;
}
void BlitPass::SetLabel(std::string label) {
if (label.empty()) {
return;
}
transients_buffer_->SetLabel(SPrintF("%s Transients", label.c_str()));
OnSetLabel(std::move(label));
}
bool BlitPass::AddCopy(std::shared_ptr<Texture> source,
std::shared_ptr<Texture> destination,
std::optional<IRect> source_region,
IPoint destination_origin,
std::string label) {
if (!source) {
VALIDATION_LOG << "Attempted to add a texture blit with no source.";
return false;
}
if (!destination) {
VALIDATION_LOG << "Attempted to add a texture blit with no destination.";
return false;
}
if (source->GetTextureDescriptor().sample_count !=
destination->GetTextureDescriptor().sample_count) {
VALIDATION_LOG << SPrintF(
"The source sample count (%d) must match the destination sample count "
"(%d) for blits.",
source->GetTextureDescriptor().sample_count,
destination->GetTextureDescriptor().sample_count);
return false;
}
if (!source_region.has_value()) {
source_region = IRect::MakeSize(source->GetSize());
}
// Clip the source image.
source_region =
source_region->Intersection(IRect::MakeSize(source->GetSize()));
if (!source_region.has_value()) {
return true; // Nothing to blit.
}
// Clip the destination image.
source_region = source_region->Intersection(
IRect(-destination_origin, destination->GetSize()));
if (!source_region.has_value()) {
return true; // Nothing to blit.
}
return OnCopyTextureToTextureCommand(
std::move(source), std::move(destination), source_region.value(),
destination_origin, std::move(label));
}
bool BlitPass::AddCopy(std::shared_ptr<Texture> source,
std::shared_ptr<DeviceBuffer> destination,
std::optional<IRect> source_region,
size_t destination_offset,
std::string label) {
if (!source) {
VALIDATION_LOG << "Attempted to add a texture blit with no source.";
return false;
}
if (!destination) {
VALIDATION_LOG << "Attempted to add a texture blit with no destination.";
return false;
}
if (!source_region.has_value()) {
source_region = IRect::MakeSize(source->GetSize());
}
auto bytes_per_pixel =
BytesPerPixelForPixelFormat(source->GetTextureDescriptor().format);
auto bytes_per_image = source_region->size.Area() * bytes_per_pixel;
if (destination_offset + bytes_per_image >
destination->GetDeviceBufferDescriptor().size) {
VALIDATION_LOG
<< "Attempted to add a texture blit with out fo bounds access.";
return false;
}
// Clip the source image.
source_region =
source_region->Intersection(IRect::MakeSize(source->GetSize()));
if (!source_region.has_value()) {
return true; // Nothing to blit.
}
return OnCopyTextureToBufferCommand(std::move(source), std::move(destination),
source_region.value(), destination_offset,
std::move(label));
}
bool BlitPass::GenerateMipmap(std::shared_ptr<Texture> texture,
std::string label) {
if (!texture) {
VALIDATION_LOG << "Attempted to add an invalid mipmap generation command "
"with no texture.";
return false;
}
return OnGenerateMipmapCommand(std::move(texture), std::move(label));
}
} // namespace impeller