blob: c82fbcc5862f3beafa9ddaa38d7f485a138e8bbd [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 "flutter/lib/gpu/shader_library.h"
#include <utility>
#include "flutter/lib/gpu/fixtures.h"
#include "flutter/lib/gpu/shader.h"
#include "fml/mapping.h"
#include "fml/memory/ref_ptr.h"
#include "impeller/renderer/vertex_descriptor.h"
#include "impeller/runtime_stage/runtime_stage.h"
namespace flutter {
namespace gpu {
// ===[ BEGIN MEMES ]===========================================================
static fml::RefPtr<Shader> OpenRuntimeStageAsShader(
std::shared_ptr<fml::Mapping> payload,
const std::shared_ptr<impeller::VertexDescriptor>& vertex_desc) {
impeller::RuntimeStage stage(std::move(payload));
return Shader::Make(stage.GetEntrypoint(),
ToShaderStage(stage.GetShaderStage()),
stage.GetCodeMapping(), stage.GetUniforms(), vertex_desc);
}
static fml::RefPtr<ShaderLibrary> InstantiateTestShaderLibrary() {
ShaderLibrary::ShaderMap shaders;
{
auto vertex_desc = std::make_shared<impeller::VertexDescriptor>();
vertex_desc->SetStageInputs(
FlutterGPUUnlitVertexShader::kAllShaderStageInputs,
FlutterGPUUnlitVertexShader::kInterleavedBufferLayout);
shaders["UnlitVertex"] = OpenRuntimeStageAsShader(
std::make_shared<fml::NonOwnedMapping>(kFlutterGPUUnlitVertIPLR,
kFlutterGPUUnlitVertIPLRLength),
vertex_desc);
shaders["UnlitFragment"] = OpenRuntimeStageAsShader(
std::make_shared<fml::NonOwnedMapping>(kFlutterGPUUnlitFragIPLR,
kFlutterGPUUnlitFragIPLRLength),
nullptr);
}
{
auto vertex_desc = std::make_shared<impeller::VertexDescriptor>();
vertex_desc->SetStageInputs(
FlutterGPUTextureVertexShader::kAllShaderStageInputs,
FlutterGPUTextureVertexShader::kInterleavedBufferLayout);
shaders["TextureVertex"] = OpenRuntimeStageAsShader(
std::make_shared<fml::NonOwnedMapping>(
kFlutterGPUTextureVertIPLR, kFlutterGPUTextureVertIPLRLength),
vertex_desc);
shaders["TextureFragment"] = OpenRuntimeStageAsShader(
std::make_shared<fml::NonOwnedMapping>(
kFlutterGPUTextureFragIPLR, kFlutterGPUTextureFragIPLRLength),
nullptr);
}
auto library = ShaderLibrary::MakeFromShaders(std::move(shaders));
return library;
}
// ===[ END MEMES ]=============================================================
IMPLEMENT_WRAPPERTYPEINFO(flutter_gpu, ShaderLibrary);
fml::RefPtr<ShaderLibrary> ShaderLibrary::override_shader_library_;
fml::RefPtr<ShaderLibrary> ShaderLibrary::MakeFromAsset(
const std::string& name,
std::string& out_error) {
// ===========================================================================
// This is a temporary hack to get the shader library populated in the
// framework before the shader bundle format is landed!
if (!override_shader_library_) {
return InstantiateTestShaderLibrary();
}
// ===========================================================================
if (override_shader_library_) {
return override_shader_library_;
}
// TODO(bdero): Load the ShaderLibrary asset.
out_error = "Shader bundle asset unimplemented";
return nullptr;
}
fml::RefPtr<ShaderLibrary> ShaderLibrary::MakeFromShaders(ShaderMap shaders) {
auto res =
fml::MakeRefCounted<flutter::gpu::ShaderLibrary>(std::move(shaders));
return res;
}
void ShaderLibrary::SetOverride(
fml::RefPtr<ShaderLibrary> override_shader_library) {
override_shader_library_ = std::move(override_shader_library);
}
fml::RefPtr<Shader> ShaderLibrary::GetShader(const std::string& shader_name,
Dart_Handle shader_wrapper) const {
auto it = shaders_.find(shader_name);
if (it == shaders_.end()) {
return nullptr; // No matching shaders.
}
auto shader = it->second;
if (shader->dart_wrapper() == nullptr) {
shader->AssociateWithDartWrapper(shader_wrapper);
}
return shader;
}
ShaderLibrary::ShaderLibrary(ShaderMap shaders)
: shaders_(std::move(shaders)) {}
ShaderLibrary::~ShaderLibrary() = default;
} // namespace gpu
} // namespace flutter
//----------------------------------------------------------------------------
/// Exports
///
Dart_Handle InternalFlutterGpu_ShaderLibrary_InitializeWithAsset(
Dart_Handle wrapper,
Dart_Handle asset_name) {
if (!Dart_IsString(asset_name)) {
return tonic::ToDart("Asset name must be a string");
}
std::string error;
auto res = flutter::gpu::ShaderLibrary::MakeFromAsset(
tonic::StdStringFromDart(asset_name), error);
if (!res) {
return tonic::ToDart(error);
}
res->AssociateWithDartWrapper(wrapper);
return Dart_Null();
}
Dart_Handle InternalFlutterGpu_ShaderLibrary_GetShader(
flutter::gpu::ShaderLibrary* wrapper,
Dart_Handle shader_name,
Dart_Handle shader_wrapper) {
FML_DCHECK(Dart_IsString(shader_name));
auto shader =
wrapper->GetShader(tonic::StdStringFromDart(shader_name), shader_wrapper);
if (!shader) {
return Dart_Null();
}
return tonic::ToDart(shader.get());
}