| // 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_ |