Skip to content

Commit

Permalink
feat: unify vertex drawing mode with vectorCmd drawing mode
Browse files Browse the repository at this point in the history
  • Loading branch information
stergiotis committed Jun 15, 2024
1 parent 2ce08ef commit f28ae96
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 142 deletions.
6 changes: 3 additions & 3 deletions skia/imgui/imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ namespace ImGui
{
#ifdef SKIA_DRAW_BACKEND
extern SkFont skiaFont;
extern bool skiaActive;
extern bool useVectorCmd;
extern float skiaFontDyFudge;
extern std::shared_ptr<Paragraph> paragraph;
constexpr unsigned int skiaPasswordDefaultCharacter = U'*'; // TODO make this configurable or runtime selectable
Expand Down Expand Up @@ -2966,10 +2966,10 @@ struct ImDrawList
#ifdef SKIA_DRAW_BACKEND
flatbuffers::FlatBufferBuilder *fbBuilder;
std::vector<flatbuffers::Offset<VectorCmdFB::SingleVectorCmdDto>> *_FbCmds;
int _FbProcessedDrawCmdIdx;
uint32_t _FbProcessedDrawCmdIndexOffset;
public: // public: ImFont needs to access this method, in spirit of the rest of imgui I do not use C++'s friend keyword
void addVectorCmdFB(VectorCmdFB::VectorCmdArg arg_type, flatbuffers::Offset<void> arg);
void addVerticesAsVectorCmd();
#ifdef SKIA_DRAW_BACKEND_PARAGRAPH_AS_PATH
ImVector<uint8_t> fPathVerbBuffer;
ImVector<float> fPathPointBuffer;
Expand Down Expand Up @@ -3240,7 +3240,7 @@ struct ImFont
IMGUI_API const ImFontGlyph*FindGlyphNoFallback(ImWchar c) const;
#ifdef SKIA_DRAW_BACKEND
float GetCharAdvance(ImWchar c) const {
if(!ImGui::skiaActive) {
if(!ImGui::useVectorCmd) {
return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX;
}

Expand Down
69 changes: 38 additions & 31 deletions skia/imgui/imgui_draw_fb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ using namespace IMGUI_STB_NAMESPACE;

#ifdef SKIA_DRAW_BACKEND
#include "tracy/Tracy.hpp"
#define SKIA_DRAW_BACKEND_BEGIN if(ImGui::skiaActive) { ZoneScoped;
#define SKIA_DRAW_BACKEND_BEGIN if(ImGui::useVectorCmd) { ZoneScoped;
#define SKIA_DRAW_BACKEND_END }
//-----------------------------------------------------------------------------
// [SECTION] Skia
Expand All @@ -183,7 +183,7 @@ using namespace IMGUI_STB_NAMESPACE;
#include "vectorCmd_generated.h"
namespace ImGui {
SkFont skiaFont;
bool skiaActive = false;
bool useVectorCmd = false;
float skiaFontDyFudge = 0.0f;
std::shared_ptr<Paragraph> paragraph = nullptr;
}
Expand Down Expand Up @@ -225,29 +225,31 @@ static inline void initHiddenPwBuffer(const ImFont &font) {
#ifdef SKIA_DRAW_BACKEND
#include "flatbufferHelpers.h"
static constexpr bool enableVectorCmdFBVertexDraw = true;
void ImDrawList::addVectorCmdFB(VectorCmdFB::VectorCmdArg arg_type, flatbuffers::Offset<void> arg) {
if(enableVectorCmdFBVertexDraw && ImGui::skiaActive) {
auto sz = CmdBuffer.Size;
if(sz >= 2) {
_TryMergeDrawCmds();
}
IM_ASSERT(_FbProcessedDrawCmdIdx >= 0);
bool added = false;
for(int i=_FbProcessedDrawCmdIdx;i<sz;i++) {
auto &cur = CmdBuffer.Data[i];
if(cur.ElemCount == 0 || cur.UserCallback != nullptr) {
continue;
}
auto cr = VectorCmdFB::SingleVec4(cur.ClipRect.x,cur.ClipRect.y,cur.ClipRect.z,cur.ClipRect.w);
auto cmd = VectorCmdFB::CreateCmdVertexDraw(*fbBuilder,&cr,cur.ElemCount,_FbProcessedDrawCmdIndexOffset,cur.VtxOffset);
_FbCmds->push_back(VectorCmdFB::CreateSingleVectorCmdDto(*fbBuilder,VectorCmdFB::VectorCmdArg_CmdVertexDraw,cmd.Union()));
_FbProcessedDrawCmdIndexOffset += cur.ElemCount;
added = true;
void ImDrawList::addVerticesAsVectorCmd() {
auto sz = CmdBuffer.Size;
if(sz >= 2) {
_TryMergeDrawCmds();
}
bool added = false;
for(int i=0;i<sz;i++) {
auto &cur = CmdBuffer.Data[i];
if(cur.ElemCount == 0 || cur.UserCallback != nullptr) {
continue;
}
if(added) {
auto cr = VectorCmdFB::SingleVec4(cur.ClipRect.x,cur.ClipRect.y,cur.ClipRect.z,cur.ClipRect.w);
auto cmd = VectorCmdFB::CreateCmdVertexDraw(*fbBuilder,&cr,cur.ElemCount,_FbProcessedDrawCmdIndexOffset,cur.VtxOffset);
_FbCmds->push_back(VectorCmdFB::CreateSingleVectorCmdDto(*fbBuilder,VectorCmdFB::VectorCmdArg_CmdVertexDraw,cmd.Union()));
_FbProcessedDrawCmdIndexOffset += cur.ElemCount;
added = true;
}
if(added) {
CmdBuffer.clear();
AddDrawCmd();
}
}
}
void ImDrawList::addVectorCmdFB(VectorCmdFB::VectorCmdArg arg_type, flatbuffers::Offset<void> arg) {
if(enableVectorCmdFBVertexDraw && ImGui::useVectorCmd) {
addVerticesAsVectorCmd();
}
_FbCmds->push_back(VectorCmdFB::CreateSingleVectorCmdDto(*fbBuilder,arg_type,arg));
}
Expand Down Expand Up @@ -293,6 +295,11 @@ static flatbuffers::Offset<VectorCmdFB::DrawList> createVectorCmdFBDrawList(ImDr
return VectorCmdFB::CreateDrawList(fbBuilder,f,name,vertices,cmds);
}
void ImDrawList::serializeFB(const uint8_t *&out,size_t &size) { ZoneScoped;
if(!ImGui::useVectorCmd) {
// no native drawing commands, add all vertices as command (this will emulate the standard ImGui backend implementation)
addVerticesAsVectorCmd();
}

auto dlFb = createVectorCmdFBDrawList(*this,false,*_FbCmds,*fbBuilder);
fbBuilder->Finish(dlFb,nullptr);
size = fbBuilder->GetSize();
Expand Down Expand Up @@ -534,8 +541,7 @@ void ImDrawList::_ResetForNewFrame()
_Splitter.Merge(this);

CmdBuffer.resize(0);
SKIA_DRAW_BACKEND_BEGIN
_FbProcessedDrawCmdIdx = 0;
#ifdef SKIA_DRAW_BACKEND
_FbProcessedDrawCmdIndexOffset = 0;
if(fbBuilder == nullptr) {
fbBuilder = new flatbuffers::FlatBufferBuilder();
Expand All @@ -547,7 +553,7 @@ SKIA_DRAW_BACKEND_BEGIN
} else {
_FbCmds->resize(0);
}
SKIA_DRAW_BACKEND_END
#endif
IdxBuffer.resize(0);
VtxBuffer.resize(0);
Flags = _Data->InitialFlags;
Expand All @@ -568,7 +574,7 @@ void ImDrawList::_ClearFreeMemory()
CmdBuffer.clear();
IdxBuffer.clear();
VtxBuffer.clear();
SKIA_DRAW_BACKEND_BEGIN
#ifdef SKIA_DRAW_BACKEND
if(fbBuilder != nullptr) {
fbBuilder->Reset();
delete fbBuilder;
Expand All @@ -584,7 +590,7 @@ SKIA_DRAW_BACKEND_BEGIN
fPathPointBuffer.clear();
fPathWeightBuffer.clear();
#endif
SKIA_DRAW_BACKEND_END
#endif
Flags = ImDrawListFlags_None;
_VtxCurrentIdx = 0;
_VtxWritePtr = NULL;
Expand Down Expand Up @@ -2419,7 +2425,7 @@ void ImDrawData::Clear()
void ImGui::AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
{ ZoneScoped;
#ifdef SKIA_DRAW_BACKEND
if(ImGui::skiaActive) {
if(ImGui::useVectorCmd) {
if(draw_list->_FbCmds->size() == 0) {
// skip empty drawlist
return;
Expand Down Expand Up @@ -4419,14 +4425,15 @@ SKIA_DRAW_BACKEND_BEGIN
if(!found) {
break;
}
//draw_list->AddRect(ImVec2(pos.x+ SkScalarToFloat(bounds.top()), pos.y+SkScalarToFloat(bounds.left())),
// ImVec2(pos.x+SkScalarToFloat(bounds.right()), pos.y+SkScalarToFloat(bounds.bottom())),
// 0xaa1199ff,0.0f,0,2.0f);
if(!bounds.intersect(clipRectSkiaTrans)) {
// clipped
continue;
}

//draw_list->AddRect(ImVec2(pos.x+ SkScalarToFloat(bounds.top()), pos.y+SkScalarToFloat(bounds.left())),
// ImVec2(pos.x+SkScalarToFloat(bounds.right()), pos.y+SkScalarToFloat(bounds.bottom())),
// 0xaa1199ff,0.0f,0,2.0f);

SkPath p;
auto unrenderedGlyphs = ImGui::paragraph->getPath(lineNumber,p);
/*
Expand Down
62 changes: 56 additions & 6 deletions skia/imgui/vectorCmd_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -3743,14 +3743,18 @@ struct CmdSvgPathSubset FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_SVG = 4,
VT_COL = 6,
VT_FILL = 8
VT_STROKE = 8,
VT_FILL = 10
};
const ::flatbuffers::String *svg() const {
return GetPointer<const ::flatbuffers::String *>(VT_SVG);
}
uint32_t col() const {
return GetField<uint32_t>(VT_COL, 0);
}
bool stroke() const {
return GetField<uint8_t>(VT_STROKE, 0) != 0;
}
bool fill() const {
return GetField<uint8_t>(VT_FILL, 0) != 0;
}
Expand All @@ -3759,6 +3763,7 @@ struct CmdSvgPathSubset FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
VerifyOffset(verifier, VT_SVG) &&
verifier.VerifyString(svg()) &&
VerifyField<uint32_t>(verifier, VT_COL, 4) &&
VerifyField<uint8_t>(verifier, VT_STROKE, 1) &&
VerifyField<uint8_t>(verifier, VT_FILL, 1) &&
verifier.EndTable();
}
Expand All @@ -3774,6 +3779,9 @@ struct CmdSvgPathSubsetBuilder {
void add_col(uint32_t col) {
fbb_.AddElement<uint32_t>(CmdSvgPathSubset::VT_COL, col, 0);
}
void add_stroke(bool stroke) {
fbb_.AddElement<uint8_t>(CmdSvgPathSubset::VT_STROKE, static_cast<uint8_t>(stroke), 0);
}
void add_fill(bool fill) {
fbb_.AddElement<uint8_t>(CmdSvgPathSubset::VT_FILL, static_cast<uint8_t>(fill), 0);
}
Expand All @@ -3792,45 +3800,61 @@ inline ::flatbuffers::Offset<CmdSvgPathSubset> CreateCmdSvgPathSubset(
::flatbuffers::FlatBufferBuilder &_fbb,
::flatbuffers::Offset<::flatbuffers::String> svg = 0,
uint32_t col = 0,
bool stroke = false,
bool fill = false) {
CmdSvgPathSubsetBuilder builder_(_fbb);
builder_.add_col(col);
builder_.add_svg(svg);
builder_.add_fill(fill);
builder_.add_stroke(stroke);
return builder_.Finish();
}

inline ::flatbuffers::Offset<CmdSvgPathSubset> CreateCmdSvgPathSubsetDirect(
::flatbuffers::FlatBufferBuilder &_fbb,
const char *svg = nullptr,
uint32_t col = 0,
bool stroke = false,
bool fill = false) {
auto svg__ = svg ? _fbb.CreateString(svg) : 0;
return VectorCmdFB::CreateCmdSvgPathSubset(
_fbb,
svg__,
col,
stroke,
fill);
}

struct CmdPath FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
typedef CmdPathBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_VERBS = 4,
VT_POINTS_XY = 6,
VT_COL = 8,
VT_FILL = 10,
VT_FILLTYPE = 12
VT_OFFSET = 4,
VT_VERBS = 6,
VT_POINTS_XY = 8,
VT_CONIC_WEIGHTS = 10,
VT_COL = 12,
VT_STROKE = 14,
VT_FILL = 16,
VT_FILLTYPE = 18
};
const VectorCmdFB::SingleVec2 *offset() const {
return GetStruct<const VectorCmdFB::SingleVec2 *>(VT_OFFSET);
}
const ::flatbuffers::Vector<uint8_t> *verbs() const {
return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_VERBS);
}
const ::flatbuffers::Vector<float> *points_xy() const {
return GetPointer<const ::flatbuffers::Vector<float> *>(VT_POINTS_XY);
}
const ::flatbuffers::Vector<float> *conic_weights() const {
return GetPointer<const ::flatbuffers::Vector<float> *>(VT_CONIC_WEIGHTS);
}
uint32_t col() const {
return GetField<uint32_t>(VT_COL, 0);
}
bool stroke() const {
return GetField<uint8_t>(VT_STROKE, 0) != 0;
}
bool fill() const {
return GetField<uint8_t>(VT_FILL, 0) != 0;
}
Expand All @@ -3839,11 +3863,15 @@ struct CmdPath FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
}
bool Verify(::flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<VectorCmdFB::SingleVec2>(verifier, VT_OFFSET, 4) &&
VerifyOffset(verifier, VT_VERBS) &&
verifier.VerifyVector(verbs()) &&
VerifyOffset(verifier, VT_POINTS_XY) &&
verifier.VerifyVector(points_xy()) &&
VerifyOffset(verifier, VT_CONIC_WEIGHTS) &&
verifier.VerifyVector(conic_weights()) &&
VerifyField<uint32_t>(verifier, VT_COL, 4) &&
VerifyField<uint8_t>(verifier, VT_STROKE, 1) &&
VerifyField<uint8_t>(verifier, VT_FILL, 1) &&
VerifyField<uint8_t>(verifier, VT_FILLTYPE, 1) &&
verifier.EndTable();
Expand All @@ -3854,15 +3882,24 @@ struct CmdPathBuilder {
typedef CmdPath Table;
::flatbuffers::FlatBufferBuilder &fbb_;
::flatbuffers::uoffset_t start_;
void add_offset(const VectorCmdFB::SingleVec2 *offset) {
fbb_.AddStruct(CmdPath::VT_OFFSET, offset);
}
void add_verbs(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> verbs) {
fbb_.AddOffset(CmdPath::VT_VERBS, verbs);
}
void add_points_xy(::flatbuffers::Offset<::flatbuffers::Vector<float>> points_xy) {
fbb_.AddOffset(CmdPath::VT_POINTS_XY, points_xy);
}
void add_conic_weights(::flatbuffers::Offset<::flatbuffers::Vector<float>> conic_weights) {
fbb_.AddOffset(CmdPath::VT_CONIC_WEIGHTS, conic_weights);
}
void add_col(uint32_t col) {
fbb_.AddElement<uint32_t>(CmdPath::VT_COL, col, 0);
}
void add_stroke(bool stroke) {
fbb_.AddElement<uint8_t>(CmdPath::VT_STROKE, static_cast<uint8_t>(stroke), 0);
}
void add_fill(bool fill) {
fbb_.AddElement<uint8_t>(CmdPath::VT_FILL, static_cast<uint8_t>(fill), 0);
}
Expand All @@ -3882,34 +3919,47 @@ struct CmdPathBuilder {

inline ::flatbuffers::Offset<CmdPath> CreateCmdPath(
::flatbuffers::FlatBufferBuilder &_fbb,
const VectorCmdFB::SingleVec2 *offset = nullptr,
::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> verbs = 0,
::flatbuffers::Offset<::flatbuffers::Vector<float>> points_xy = 0,
::flatbuffers::Offset<::flatbuffers::Vector<float>> conic_weights = 0,
uint32_t col = 0,
bool stroke = false,
bool fill = false,
VectorCmdFB::PathFillType fillType = VectorCmdFB::PathFillType_winding) {
CmdPathBuilder builder_(_fbb);
builder_.add_col(col);
builder_.add_conic_weights(conic_weights);
builder_.add_points_xy(points_xy);
builder_.add_verbs(verbs);
builder_.add_offset(offset);
builder_.add_fillType(fillType);
builder_.add_fill(fill);
builder_.add_stroke(stroke);
return builder_.Finish();
}

inline ::flatbuffers::Offset<CmdPath> CreateCmdPathDirect(
::flatbuffers::FlatBufferBuilder &_fbb,
const VectorCmdFB::SingleVec2 *offset = nullptr,
const std::vector<uint8_t> *verbs = nullptr,
const std::vector<float> *points_xy = nullptr,
const std::vector<float> *conic_weights = nullptr,
uint32_t col = 0,
bool stroke = false,
bool fill = false,
VectorCmdFB::PathFillType fillType = VectorCmdFB::PathFillType_winding) {
auto verbs__ = verbs ? _fbb.CreateVector<uint8_t>(*verbs) : 0;
auto points_xy__ = points_xy ? _fbb.CreateVector<float>(*points_xy) : 0;
auto conic_weights__ = conic_weights ? _fbb.CreateVector<float>(*conic_weights) : 0;
return VectorCmdFB::CreateCmdPath(
_fbb,
offset,
verbs__,
points_xy__,
conic_weights__,
col,
stroke,
fill,
fillType);
}
Expand Down
12 changes: 7 additions & 5 deletions skia/skia/cliOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ void CliOptions::usage(const char *name, FILE *file) const {
fprintf(file," bool flags:\n");
fprintf(file," -fffiInterpreter [bool:%s]\n",fffiInterpreter ? "on" : "off");
fprintf(file," -vsync [bool:%s]\n",vsync ? "on" : "off");
fprintf(file, " -backdropFilter [bool:%s]\n", backdropFilter ? "on" : "off");
fprintf(file, " -sketchFilter [bool:%s]\n", sketchFilter ? "on" : "off");
fprintf(file, " -imguiNavKeyboard [bool:%s]\n", imguiNavKeyboard ? "on" : "off");
fprintf(file, " -imguiNavGamepad [bool:%s]\n", imguiNavGamepad ? "on" : "off");
fprintf(file, " -imguiDocking [bool:%s]\n", imguiDocking ? "on" : "off");
fprintf(file," -backdropFilter [bool:%s]\n", backdropFilter ? "on" : "off");
fprintf(file," -sketchFilter [bool:%s]\n", sketchFilter ? "on" : "off");
fprintf(file," -imguiNavKeyboard [bool:%s]\n", imguiNavKeyboard ? "on" : "off");
fprintf(file," -imguiNavGamepad [bool:%s]\n", imguiNavGamepad ? "on" : "off");
fprintf(file," -imguiDocking [bool:%s]\n", imguiDocking ? "on" : "off");
fprintf(file," -vectorCmd [bool:%s] on: intercept ImGui DrawList draw commands and replay them on client (e.g. skia)\n", vectorCmd ? "on" : "off");
}
void CliOptions::parse(int argc,char **argv,FILE *logChannel) {
if(argc > 1) {
Expand Down Expand Up @@ -94,6 +95,7 @@ void CliOptions::parse(int argc,char **argv,FILE *logChannel) {
imguiNavKeyboard = getBoolFlagValue(logChannel,u, argc, argv, "-imguiNavKeyboard",imguiNavKeyboard);
imguiNavGamepad = getBoolFlagValue(logChannel,u, argc, argv, "-imguiNavGamepad",imguiNavGamepad);
imguiDocking = getBoolFlagValue(logChannel,u, argc, argv, "-imguiDocking",imguiDocking);
vectorCmd = getBoolFlagValue(logChannel,u, argc, argv, "-vectorCmd",vectorCmd);

if(std::popcount(u) != (argc-1)) {
for(int i=1;i<argc;i++) {
Expand Down
Loading

0 comments on commit f28ae96

Please sign in to comment.