1
0
Fork 0
mirror of https://github.com/Atmosphere-NX/Atmosphere.git synced 2024-11-15 00:16:48 +00:00
Atmosphere/troposphere/daybreak/nanovg/include/nanovg/dk_renderer.hpp
2021-04-29 01:21:09 -07:00

208 lines
No EOL
6.1 KiB
C++

#pragma once
#include <deko3d.hpp>
#include <map>
#include <memory>
#include <vector>
#include <optional>
#include "framework/CDescriptorSet.h"
#include "framework/CMemPool.h"
#include "framework/CShader.h"
#include "framework/CCmdMemRing.h"
#include "nanovg.h"
// Create flags
enum NVGcreateFlags {
// Flag indicating if geometry based anti-aliasing is used (may not be needed when using MSAA).
NVG_ANTIALIAS = 1<<0,
// Flag indicating if strokes should be drawn using stencil buffer. The rendering will be a little
// slower, but path overlaps (i.e. self-intersecting or sharp turns) will be drawn just once.
NVG_STENCIL_STROKES = 1<<1,
// Flag indicating that additional debug checks are done.
NVG_DEBUG = 1<<2,
};
enum DKNVGuniformLoc
{
DKNVG_LOC_VIEWSIZE,
DKNVG_LOC_TEX,
DKNVG_LOC_FRAG,
DKNVG_MAX_LOCS
};
enum VKNVGshaderType {
NSVG_SHADER_FILLGRAD,
NSVG_SHADER_FILLIMG,
NSVG_SHADER_SIMPLE,
NSVG_SHADER_IMG
};
struct DKNVGtextureDescriptor {
int width, height;
int type;
int flags;
};
struct DKNVGblend {
int srcRGB;
int dstRGB;
int srcAlpha;
int dstAlpha;
};
enum DKNVGcallType {
DKNVG_NONE = 0,
DKNVG_FILL,
DKNVG_CONVEXFILL,
DKNVG_STROKE,
DKNVG_TRIANGLES,
};
struct DKNVGcall {
int type;
int image;
int pathOffset;
int pathCount;
int triangleOffset;
int triangleCount;
int uniformOffset;
DKNVGblend blendFunc;
};
struct DKNVGpath {
int fillOffset;
int fillCount;
int strokeOffset;
int strokeCount;
};
struct DKNVGfragUniforms {
float scissorMat[12]; // matrices are actually 3 vec4s
float paintMat[12];
struct NVGcolor innerCol;
struct NVGcolor outerCol;
float scissorExt[2];
float scissorScale[2];
float extent[2];
float radius;
float feather;
float strokeMult;
float strokeThr;
int texType;
int type;
};
namespace nvg {
class DkRenderer;
}
struct DKNVGcontext {
nvg::DkRenderer *renderer;
float view[2];
int fragSize;
int flags;
// Per frame buffers
DKNVGcall* calls;
int ccalls;
int ncalls;
DKNVGpath* paths;
int cpaths;
int npaths;
struct NVGvertex* verts;
int cverts;
int nverts;
unsigned char* uniforms;
int cuniforms;
int nuniforms;
};
namespace nvg {
class Texture {
private:
const int m_id;
dk::Image m_image;
dk::ImageDescriptor m_image_descriptor;
CMemPool::Handle m_image_mem;
DKNVGtextureDescriptor m_texture_descriptor;
public:
Texture(int id);
~Texture();
void Initialize(CMemPool &image_pool, CMemPool &scratch_pool, dk::Device device, dk::Queue transfer_queue, int type, int w, int h, int image_flags, const u8 *data);
void Update(CMemPool &image_pool, CMemPool &scratch_pool, dk::Device device, dk::Queue transfer_queue, int type, int w, int h, int image_flags, const u8 *data);
int GetId();
const DKNVGtextureDescriptor &GetDescriptor();
dk::Image &GetImage();
dk::ImageDescriptor &GetImageDescriptor();
};
class DkRenderer {
private:
enum SamplerType : u8 {
SamplerType_MipFilter = 1 << 0,
SamplerType_Nearest = 1 << 1,
SamplerType_RepeatX = 1 << 2,
SamplerType_RepeatY = 1 << 3,
SamplerType_Total = 0x10,
};
private:
static constexpr size_t DynamicCmdSize = 0x20000;
static constexpr size_t FragmentUniformSize = sizeof(DKNVGfragUniforms) + 4 - sizeof(DKNVGfragUniforms) % 4;
static constexpr size_t MaxImages = 0x1000;
/* From the application. */
u32 m_view_width;
u32 m_view_height;
dk::Device m_device;
dk::Queue m_queue;
CMemPool &m_image_mem_pool;
CMemPool &m_code_mem_pool;
CMemPool &m_data_mem_pool;
/* State. */
dk::UniqueCmdBuf m_dyn_cmd_buf;
CCmdMemRing<1> m_dyn_cmd_mem;
std::optional<CMemPool::Handle> m_vertex_buffer;
CShader m_vertex_shader;
CShader m_fragment_shader;
CMemPool::Handle m_view_uniform_buffer;
CMemPool::Handle m_frag_uniform_buffer;
u32 m_next_texture_id = 1;
std::vector<std::shared_ptr<Texture>> m_textures;
CDescriptorSet<MaxImages> m_image_descriptor_set;
CDescriptorSet<SamplerType_Total> m_sampler_descriptor_set;
std::array<int, MaxImages> m_image_descriptor_mappings;
int m_last_image_descriptor = 0;
int AcquireImageDescriptor(std::shared_ptr<Texture> texture, int image);
void FreeImageDescriptor(int image);
void SetUniforms(const DKNVGcontext &ctx, int offset, int image);
void UpdateVertexBuffer(const void *data, size_t size);
void DrawFill(const DKNVGcontext &ctx, const DKNVGcall &call);
void DrawConvexFill(const DKNVGcontext &ctx, const DKNVGcall &call);
void DrawStroke(const DKNVGcontext &ctx, const DKNVGcall &call);
void DrawTriangles(const DKNVGcontext &ctx, const DKNVGcall &call);
std::shared_ptr<Texture> FindTexture(int id);
public:
DkRenderer(unsigned int view_width, unsigned int view_height, dk::Device device, dk::Queue queue, CMemPool &image_mem_pool, CMemPool &code_mem_pool, CMemPool &data_mem_pool);
~DkRenderer();
int Create(DKNVGcontext &ctx);
int CreateTexture(const DKNVGcontext &ctx, int type, int w, int h, int image_flags, const u8 *data);
int DeleteTexture(const DKNVGcontext &ctx, int id);
int UpdateTexture(const DKNVGcontext &ctx, int id, int x, int y, int w, int h, const u8 *data);
int GetTextureSize(const DKNVGcontext &ctx, int id, int *w, int *h);
const DKNVGtextureDescriptor *GetTextureDescriptor(const DKNVGcontext &ctx, int id);
void Flush(DKNVGcontext &ctx);
};
}