blob: c88b7ade488d341d4be47ec63a793e71aa41507f [file] [log] [blame]
// Copyright 2018 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 SRC_UI_LIB_ESCHER_PAPER_PAPER_DRAW_CALL_FACTORY_H_
#define SRC_UI_LIB_ESCHER_PAPER_PAPER_DRAW_CALL_FACTORY_H_
#include "src/ui/lib/escher/geometry/types.h"
#include "src/ui/lib/escher/paper/paper_drawable_flags.h"
#include "src/ui/lib/escher/paper/paper_readme.h"
#include "src/ui/lib/escher/paper/paper_renderer_config.h"
#include "src/ui/lib/escher/paper/paper_shader_list.h"
#include "src/ui/lib/escher/renderer/uniform_binding.h"
#include "src/ui/lib/escher/util/hash_map.h"
namespace escher {
struct RoundedRectSpec;
// |PaperDrawCallFactory| is responsible for generating |PaperDrawCalls| and
// enqueuing them on a |PaperRenderQueue|. It is hidden from clients of
// |PaperRenderer|, except for those who implement their own subclasses of
// |PaperDrawable|.
class PaperDrawCallFactory final {
public:
// |weak_escher| is used only to create |white_texture_|; it is not retained.
PaperDrawCallFactory(EscherWeakPtr weak_escher, const PaperRendererConfig& config);
PaperDrawCallFactory(const PaperDrawCallFactory&) = delete;
~PaperDrawCallFactory();
// Draw the specified shape by obtaining a mesh from |PaperShapeCache| and
// generating/enqueuing draw calls via |EnqueueDrawCalls()|.
void DrawCircle(float radius, const PaperMaterial& material, PaperDrawableFlags flags = {});
void DrawRect(vec2 min, vec2 max, const PaperMaterial& material, PaperDrawableFlags flags = {});
void DrawRoundedRect(const RoundedRectSpec& spec, const PaperMaterial& material,
PaperDrawableFlags flags = {});
void DrawBoundingBox(const PaperMaterial& material, PaperDrawableFlags flags = {});
// We are currently unable to clip meshes that are already provided to us and not generated
// from the PaperShapeCache, and so we render them directly without doing any clipping. It is
// possible to clip on the GPU, but this functionality is not available on all hardware, and
// performing clipping on the GPU means our existing stencil shadow implementation will no
// longer work.
void DrawMesh(const MeshPtr& mesh, const PaperMaterial& material, PaperDrawableFlags flags = {});
// Must not be called during a frame, i.e. between |BeginFrame()| and |EndFrame()|.
void SetConfig(const PaperRendererConfig& config);
// TODO(ES203) - We will eventualy not need to do this as we will simply
// inject PaperRenderer with a version of the PaperDrawCallFactory that
// is used explicitly for testing.
//
// When this is set to true, no draw calls get enqueued and instead,
// PaperDrawCallFactory will accumulate a list of cache entries that
// would have been drawn.
void set_track_cache_entries(bool track) { track_cache_entries_ = track; }
const std::vector<PaperShapeCacheEntry>& tracked_cache_entries() const {
return tracked_cache_entries_;
}
// Helper for the creation of uint64_t sort-keys for the opaque and
// translucent RenderQueues.
class SortKey {
public:
static SortKey NewOpaque(Hash pipeline_hash, Hash draw_hash, float depth);
static SortKey NewTranslucent(Hash pipeline_hash, Hash draw_hash, float depth);
static SortKey NewWireframe(Hash pipeline_hash, Hash draw_hash, float depth);
SortKey(const SortKey& other) : key_(other.key_) {}
uint64_t key() const { return key_; }
private:
SortKey(uint64_t key) : key_(key) {}
uint64_t key_;
};
private:
friend class PaperRenderer;
friend class PaperTester;
// Called by |PaperRenderer::BeginFrame()|. Returns a vector of
// UniformBindings; PaperRenderer should bind these before directing the
// PaperRenderQueue to emit commands into a CommandBuffer.
//
// |frame| is used to allocate per-frame memory for draw-calls.
//
// |scene| and |camera| are used to generate the |UniformBindings| that are
// returned from this method, which contain camera and lighting parameters
// that are shared between multiple draw calls. This data is opaque to
// |PaperRenderer|; the precise format is specific to the configuration set
// by |SetConfig()|.
//
// |transform_stack| is used to obtain the model-to-world matrix that is part
// of each draw call, and to provide clip-planes when obtaining cached meshes
// from |shape_cache|.
//
// |camera| and |transform_stack| could be used to obtain LOD-appropriate
// meshes from |shape_cache|, but this is not currently implemented.
void BeginFrame(const FramePtr& frame, BatchGpuUploader* uploader, PaperScene* scene,
PaperTransformStack* transform_stack, PaperRenderQueue* render_queue,
PaperShapeCache* shape_cache, vec3 camera_pos, vec3 camera_dir);
// Cleanup.
void EndFrame();
// Generate and enqueue 0 or more draw calls for the mesh/material combo.
// The mesh is transformed into world space by the matrix atop the transform
// stack.
void EnqueueDrawCalls(const PaperShapeCacheEntry& cache_entry, const PaperMaterial& material,
PaperDrawableFlags flags);
// Return the list of shaders that "will" be used to render a mesh. For simplicity, some shaders
// may be provided which won't be used, for example if shadows are disabled then the shaders for
// shadow-volume generation will be ignored.
PaperShaderList GetShaderList(const Material& mat, bool cast_shadows) const;
PaperRendererConfig config_;
// Rather than using a separate Vulkan pipeline for Materials that have no
// texture (only a color), we use a 1x1 texture with a single white pixel.
// This is simpler to implement and avoids the cost of switching pipelines.
TexturePtr white_texture_;
ShaderProgramPtr ambient_light_program_;
ShaderProgramPtr no_lighting_program_;
ShaderProgramPtr point_light_program_;
ShaderProgramPtr shadow_volume_geometry_program_;
ShaderProgramPtr shadow_volume_geometry_debug_program_;
FramePtr frame_;
PaperTransformStack* transform_stack_ = nullptr;
PaperRenderQueue* render_queue_ = nullptr;
PaperShapeCache* shape_cache_ = nullptr;
vec3 camera_pos_;
vec3 camera_dir_;
// Cache for |object_data| used by RenderQueueItems in both the opaque and
// translucent queues.
HashMap<Hash, void*> object_data_;
bool track_cache_entries_ = false;
std::vector<PaperShapeCacheEntry> tracked_cache_entries_;
};
} // namespace escher
#endif // SRC_UI_LIB_ESCHER_PAPER_PAPER_DRAW_CALL_FACTORY_H_