blob: 90f489dcfa45f0f7e46d471d9f9625f83afe7a8f [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/entity/contents/gradient_generator.h"
#include "flutter/fml/logging.h"
#include "impeller/base/strings.h"
#include "impeller/core/device_buffer.h"
#include "impeller/core/formats.h"
#include "impeller/core/texture.h"
#include "impeller/renderer/context.h"
namespace impeller {
std::shared_ptr<Texture> CreateGradientTexture(
const GradientData& gradient_data,
const std::shared_ptr<impeller::Context>& context) {
if (gradient_data.texture_size == 0) {
FML_DLOG(ERROR) << "Invalid gradient data.";
return nullptr;
}
impeller::TextureDescriptor texture_descriptor;
texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
texture_descriptor.size = {gradient_data.texture_size, 1};
auto texture =
context->GetResourceAllocator()->CreateTexture(texture_descriptor);
if (!texture) {
FML_DLOG(ERROR) << "Could not create Impeller texture.";
return nullptr;
}
auto data_mapping =
std::make_shared<fml::DataMapping>(gradient_data.color_bytes);
auto buffer =
context->GetResourceAllocator()->CreateBufferWithCopy(*data_mapping);
auto cmd_buffer = context->CreateCommandBuffer();
auto blit_pass = cmd_buffer->CreateBlitPass();
blit_pass->AddCopy(DeviceBuffer::AsBufferView(std::move(buffer)), texture);
if (!blit_pass->EncodeCommands(context->GetResourceAllocator()) ||
!context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok()) {
return nullptr;
}
texture->SetLabel(impeller::SPrintF("Gradient(%p)", texture.get()).c_str());
return texture;
}
std::vector<StopData> CreateGradientColors(const std::vector<Color>& colors,
const std::vector<Scalar>& stops) {
FML_DCHECK(stops.size() == colors.size());
std::vector<StopData> result;
result.reserve(stops.size());
Scalar last_stop = 0;
for (auto i = 0u; i < stops.size(); i++) {
Scalar delta = stops[i] - last_stop;
Scalar inverse_delta = delta == 0.0f ? 0.0 : 1.0 / delta;
result.emplace_back(StopData{
.color = colors[i], .stop = stops[i], .inverse_delta = inverse_delta});
last_stop = stops[i];
}
return result;
}
} // namespace impeller