HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
pipeline_SDF_device_shared.hpp
1// Copyright Take Vos 2020-2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "pipeline_SDF_texture_map.hpp"
8#include "pipeline_SDF_specialization_constants.hpp"
9#include "../text/glyph_ids.hpp"
10#include "../text/glyph_atlas_info.hpp"
11#include "../required.hpp"
12#include "../log.hpp"
13#include "../vspan.hpp"
14#include "../geometry/rectangle.hpp"
15#include "../geometry/scale.hpp"
16#include "../geometry/transform.hpp"
17#include "../color/quad_color.hpp"
18#include <vk_mem_alloc.h>
19#include <vulkan/vulkan.hpp>
20#include <mutex>
21#include <unordered_map>
22
23namespace hi::inline v1 {
24template<typename T>
25class pixel_map;
26class mat;
27class gfx_device_vulkan;
28class shaped_text;
29struct attributed_glyph;
30
31namespace pipeline_SDF {
32struct Image;
33struct vertex;
34
35struct device_shared final {
36 // Studies in China have shown that literate individuals know and use between 3,000 and 4,000 characters.
37 // Handle up to 7 * 7 * 128 == 6321 characters with a 16 x 1024 x 1024, 16 x 1 MByte
38 //
39 // For latin characters we can store about 7 * 12 == 84 characters in a single image, which is enough
40 // for the full alpha numeric range that an application will use.
41
42 static constexpr int atlasImageWidth = 256; // 7-12 characters, of 34 pixels wide.
43 static constexpr int atlasImageHeight = 256; // 7 characters, of 34 pixels height.
44 static_assert(atlasImageWidth == atlasImageHeight, "needed for fwidth(textureCoord)");
45
46 static constexpr int atlasMaximumNrImages = 128; // 128 * 49 characters.
47 static constexpr int stagingImageWidth = 64; // One 'em' is 28 pixels, with edges 34 pixels.
48 static constexpr int stagingImageHeight = 64;
49
50 static constexpr float atlasTextureCoordinateMultiplier = 1.0f / atlasImageWidth;
51 static constexpr float drawfontSize = 28.0f;
52 static constexpr float drawBorder = sdf_r8::max_distance;
53 static constexpr float scaledDrawBorder = drawBorder / drawfontSize;
54
55 gfx_device_vulkan const &device;
56
57 vk::ShaderModule vertexShaderModule;
58 vk::ShaderModule fragmentShaderModule;
59
60 specialization_constants specializationConstants;
61 std::vector<vk::SpecializationMapEntry> fragmentShaderSpecializationMapEntries;
62 vk::SpecializationInfo fragmentShaderSpecializationInfo;
64
65 texture_map stagingTexture;
66 std::vector<texture_map> atlasTextures;
67
69 vk::Sampler atlasSampler;
70 vk::DescriptorImageInfo atlasSamplerDescriptorImageInfo;
71
72 point3 atlas_allocation_position = {};
74 int atlasAllocationMaxHeight = 0;
75
76 device_shared(gfx_device_vulkan const &device);
78
79 device_shared(device_shared const &) = delete;
80 device_shared &operator=(device_shared const &) = delete;
81 device_shared(device_shared &&) = delete;
82 device_shared &operator=(device_shared &&) = delete;
83
88 void destroy(gfx_device_vulkan *vulkanDevice);
89
93 [[nodiscard]] glyph_atlas_info allocate_rect(extent2 draw_extent, scale2 draw_scale) noexcept;
94
95 void drawInCommandBuffer(vk::CommandBuffer &commandBuffer);
96
101
105
109
112 void prepareAtlas(shaped_text const &text) noexcept;
113
116 aarectangle get_bounding_box(glyph_ids const &glyphs) const noexcept;
117
129 vspan<vertex> &vertices,
130 aarectangle const &clipping_rectangle,
131 quad const &box,
132 glyph_ids const &glyphs,
133 quad_color colors) noexcept;
134
135private:
136 void buildShaders();
137 void teardownShaders(gfx_device_vulkan *vulkanDevice);
138 void addAtlasImage();
139 void buildAtlas();
140 void teardownAtlas(gfx_device_vulkan *vulkanDevice);
141 void add_glyph_to_atlas(glyph_ids const &glyph, glyph_atlas_info &info) noexcept;
142
146 hi_force_inline std::pair<glyph_atlas_info const *, bool> get_glyph_from_atlas(glyph_ids const &glyph) noexcept
147 {
148 auto &info = glyph.atlas_info();
149
150 if (info) [[likely]] {
151 return {&info, false};
152
153 } else {
154 add_glyph_to_atlas(glyph, info);
155 return {&info, true};
156 }
157 }
158};
159
160} // namespace pipeline_SDF
161} // namespace hi::inline v1
This file includes required definitions.
Definition quad_color.hpp:9
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
Definition quad.hpp:14
Definition gfx_device_vulkan.hpp:20
Definition pipeline_SDF_device_shared.hpp:35
void destroy(gfx_device_vulkan *vulkanDevice)
void prepareStagingPixmapForDrawing()
This will transition the staging texture to 'general' for writing by the CPU.
glyph_atlas_info allocate_rect(extent2 draw_extent, scale2 draw_scale) noexcept
Allocate an glyph in the atlas.
aarectangle get_bounding_box(glyph_ids const &glyphs) const noexcept
Get the bounding box, including draw border of a glyph.
void prepareAtlas(shaped_text const &text) noexcept
Prepare the atlas for drawing a text.
void uploadStagingPixmapToAtlas(glyph_atlas_info const &location)
Once drawing in the staging pixmap is completed, you can upload it to the atlas.
bool place_vertices(vspan< vertex > &vertices, aarectangle const &clipping_rectangle, quad const &box, glyph_ids const &glyphs, quad_color colors) noexcept
Place vertices for a single glyph.
void prepare_atlas_for_rendering()
This will transition the atlas to 'shader-read'.
Definition pipeline_SDF_specialization_constants.hpp:12
Definition pipeline_SDF_texture_map.hpp:18
Definition glyph_atlas_info.hpp:12
A set of glyph-ids of a font which composites into a single glyph.
Definition glyph_ids.hpp:127
Definition vspan.hpp:134