blob: 56594b3c4e3d7a8c43a29730a1556789ee915a55 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef GARNET_EXAMPLES_UI_SHADERTOY_SERVICE_COMPILER_H_
#define GARNET_EXAMPLES_UI_SHADERTOY_SERVICE_COMPILER_H_
#include <functional>
#include <mutex>
#include <queue>
#include <thread>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fit/function.h>
#include <vulkan/vulkan.hpp>
#include "garnet/examples/ui/shadertoy/service/pipeline.h"
#include "src/ui/lib/escher/escher.h"
#include "src/ui/lib/escher/impl/model_data.h"
namespace shadertoy {
// The Shadertoy Compiler takes a GLSL source code fragment, transforms it by
// adding a header etc., compiles it, and generates a Pipeline that can be used
// by Renderer. This is all done asynchronously; a callback is invoked when
// finished.
class Compiler final {
public:
// |render_pass| is not owned by us; we don't need to destroy it.
explicit Compiler(async::Loop* loop, escher::EscherWeakPtr escher,
vk::RenderPass render_pass,
vk::DescriptorSetLayout descriptor_set_layout);
~Compiler();
static const vk::DescriptorSetLayoutCreateInfo&
GetDescriptorSetLayoutCreateInfo();
// Result that is asynchronously returned by the Compiler.
struct Result {
PipelinePtr pipeline;
};
// Callback that is used to asynchronously notify clients of the result.
using ResultCallback = fit::function<void(Result)>;
// Compile GLSL source code on a background thread, and post a task to invoke
// ResultCallback on the main thread.
void Compile(std::string glsl, ResultCallback callback);
private:
struct Request {
std::string glsl;
ResultCallback callback;
};
PipelinePtr CompilePipeline(vk::ShaderModule vertex_module,
vk::ShaderModule fragment_module,
const escher::MeshSpec& mesh_spec);
escher::impl::GlslToSpirvCompiler* glsl_compiler();
// Drains the request queue in a background thread spawned by Compile().
void ProcessRequestQueue();
// Attempt to create a pipeline by compiling the provided GLSL code.
// Invoked by ProcessRequestQueue().
PipelinePtr CompileGlslToPipeline(const std::string& glsl_code);
// Helper for CompileGlslToPipeline.
PipelinePtr ConstructPipeline(vk::ShaderModule vertex_module,
vk::ShaderModule fragment_module,
const escher::MeshSpec& mesh_spec);
async::Loop* const loop_;
const escher::EscherWeakPtr escher_;
escher::impl::ModelDataPtr model_data_;
vk::RenderPass render_pass_;
vk::DescriptorSetLayout descriptor_set_layout_;
std::mutex mutex_;
std::queue<Request> requests_;
std::thread thread_;
bool has_thread_ = false;
};
} // namespace shadertoy
#endif // GARNET_EXAMPLES_UI_SHADERTOY_SERVICE_COMPILER_H_