blob: 97536caf752153cc5ef78716dd59cdfceefc7f8a [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 <memory>
#include <sstream>
#include "display_list/display_list_runtime_effect.h"
#include "flutter/lib/ui/painting/fragment_program.h"
#include "flutter/assets/asset_manager.h"
#include "flutter/fml/trace_event.h"
#include "flutter/impeller/runtime_stage/runtime_stage.h"
#include "flutter/lib/ui/dart_wrapper.h"
#include "flutter/lib/ui/ui_dart_state.h"
#include "flutter/lib/ui/window/platform_configuration.h"
#include "third_party/skia/include/core/SkString.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/dart_args.h"
#include "third_party/tonic/dart_binding_macros.h"
#include "third_party/tonic/dart_library_natives.h"
#include "third_party/tonic/typed_data/typed_list.h"
namespace flutter {
IMPLEMENT_WRAPPERTYPEINFO(ui, FragmentProgram);
std::string FragmentProgram::initFromAsset(const std::string& asset_name) {
FML_TRACE_EVENT("flutter", "FragmentProgram::initFromAsset", "asset",
asset_name);
std::shared_ptr<AssetManager> asset_manager = UIDartState::Current()
->platform_configuration()
->client()
->GetAssetManager();
std::unique_ptr<fml::Mapping> data = asset_manager->GetAsMapping(asset_name);
if (data == nullptr) {
return std::string("Asset '") + asset_name + std::string("' not found");
}
auto runtime_stage = impeller::RuntimeStage(std::move(data));
if (!runtime_stage.IsValid()) {
return std::string("Asset '") + asset_name +
std::string("' does not contain valid shader data.");
}
int sampled_image_count = 0;
size_t other_uniforms_bytes = 0;
for (const auto& uniform_description : runtime_stage.GetUniforms()) {
if (uniform_description.type ==
impeller::RuntimeUniformType::kSampledImage) {
sampled_image_count++;
} else {
other_uniforms_bytes += uniform_description.GetSize();
}
}
if (UIDartState::Current()->IsImpellerEnabled()) {
runtime_effect_ = DlRuntimeEffect::MakeImpeller(
std::make_unique<impeller::RuntimeStage>(std::move(runtime_stage)));
} else {
auto code_mapping = runtime_stage.GetSkSLMapping();
auto code_size = code_mapping->GetSize();
const char* sksl =
reinterpret_cast<const char*>(code_mapping->GetMapping());
// SkString makes a copy.
SkRuntimeEffect::Result result =
SkRuntimeEffect::MakeForShader(SkString(sksl, code_size));
if (result.effect == nullptr) {
return std::string("Invalid SkSL:\n") + sksl +
std::string("\nSkSL Error:\n") + result.errorText.c_str();
}
runtime_effect_ = DlRuntimeEffect::MakeSkia(result.effect);
}
Dart_Handle ths = Dart_HandleFromWeakPersistent(dart_wrapper());
if (Dart_IsError(ths)) {
Dart_PropagateError(ths);
}
Dart_Handle result = Dart_SetField(ths, tonic::ToDart("_samplerCount"),
Dart_NewInteger(sampled_image_count));
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
size_t rounded_uniform_bytes =
(other_uniforms_bytes + sizeof(float) - 1) & ~(sizeof(float) - 1);
size_t float_count = rounded_uniform_bytes / sizeof(float);
result = Dart_SetField(ths, tonic::ToDart("_uniformFloatCount"),
Dart_NewInteger(float_count));
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
return "";
}
std::shared_ptr<DlColorSource> FragmentProgram::MakeDlColorSource(
std::shared_ptr<std::vector<uint8_t>> float_uniforms,
const std::vector<std::shared_ptr<DlColorSource>>& children) {
return DlColorSource::MakeRuntimeEffect(runtime_effect_, children,
std::move(float_uniforms));
}
void FragmentProgram::Create(Dart_Handle wrapper) {
auto res = fml::MakeRefCounted<FragmentProgram>();
res->AssociateWithDartWrapper(wrapper);
}
FragmentProgram::FragmentProgram() = default;
FragmentProgram::~FragmentProgram() = default;
} // namespace flutter