diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp index e3c3b915d2c..623ac90a4c9 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp @@ -209,15 +209,15 @@ - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons. - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "open" state of a popup. BeginPopup() returns true if the popup is opened. - 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same). - - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function (will obsolete). + - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function until 1.50. - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead. - - 2015/03/17 (1.36) - renamed GetItemBoxMin()/GetItemBoxMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete). + - 2015/03/17 (1.36) - renamed GetItemBoxMin()/GetItemBoxMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function until 1.50. - 2015/03/15 (1.36) - renamed style.TreeNodeSpacing to style.IndentSpacing, ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing - - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function (will obsolete). + - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function until 1.50. - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth (casing) - - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function (will obsolete). + - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function until 1.50. - 2015/02/27 (1.34) - renamed ImGuiSetCondition_*** to ImGuiSetCond_***, and _FirstUseThisSession becomes _Once. - 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now. - 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior @@ -1202,6 +1202,20 @@ ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) return out; } +ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) +{ + ImVec4 c = GImGui->Style.Colors[idx]; + c.w *= GImGui->Style.Alpha * alpha_mul; + return ImGui::ColorConvertFloat4ToU32(c); +} + +ImU32 ImGui::GetColorU32(const ImVec4& col) +{ + ImVec4 c = col; + c.w *= GImGui->Style.Alpha; + return ImGui::ColorConvertFloat4ToU32(c); +} + // Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592 // Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) @@ -1841,7 +1855,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_offset_y) window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); - //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, 0xFF0000FF, 4); // Debug + //window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // Debug window->DC.PrevLineHeight = line_height; window->DC.PrevLineTextBaseOffset = text_base_offset; @@ -2693,10 +2707,10 @@ void ImGui::Render() const ImVec2 size = cursor_data.Size; const ImTextureID tex_id = g.IO.Fonts->TexID; g.OverlayDrawList.PushTextureID(tex_id); - g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0x30000000); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0x30000000); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], 0xFF000000); // Black border - g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[0], cursor_data.TexUvMax[0], 0xFFFFFFFF); // White fill + g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(1,0), pos+ImVec2(1,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos+ImVec2(2,0), pos+ImVec2(2,0) + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[1], cursor_data.TexUvMax[1], IM_COL32(0,0,0,255)); // Black border + g.OverlayDrawList.AddImage(tex_id, pos, pos + size, cursor_data.TexUvMin[0], cursor_data.TexUvMax[0], IM_COL32(255,255,255,255)); // White fill g.OverlayDrawList.PopTextureID(); } if (!g.OverlayDrawList.VtxBuffer.empty()) @@ -6172,7 +6186,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args) const char* text_begin = g.TempBuffer; const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - const ImVec2 label_size = CalcTextSize(text_begin, text_end, true); + const ImVec2 label_size = CalcTextSize(text_begin, text_end, false); const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize); const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x*2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding @@ -6182,7 +6196,7 @@ void ImGui::BulletTextV(const char* fmt, va_list args) // Render RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f)); - RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end); + RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end, false); } void ImGui::BulletText(const char* fmt, ...) @@ -9108,6 +9122,12 @@ bool ImGui::IsRectVisible(const ImVec2& size) return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); } +bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) +{ + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); +} + // Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) void ImGui::BeginGroup() { diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h index 6a1ed055964..24cb7715449 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h @@ -409,7 +409,8 @@ namespace ImGui IMGUI_API bool IsRootWindowFocused(); // is current root window focused (root = top-most parent of a child, otherwise self) IMGUI_API bool IsRootWindowOrAnyChildFocused(); // is current root window or any of its child (including current window) focused IMGUI_API bool IsRootWindowOrAnyChildHovered(); // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup) - IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle of given size starting from cursor pos is visible (not clipped). to perform coarse clipping on user's side (as an optimization) + IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. + IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window IMGUI_API float GetTime(); IMGUI_API int GetFrameCount(); @@ -467,15 +468,9 @@ namespace ImGui static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+ static inline ImFont* GetWindowFont() { return GetFont(); } // OBSOLETE 1.48+ static inline float GetWindowFontSize() { return GetFontSize(); } // OBSOLETE 1.48+ - static inline void OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpen(open, 0); } // OBSOLETE 1.34+ - static inline bool GetWindowIsFocused() { return ImGui::IsWindowFocused(); } // OBSOLETE 1.36+ - static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+ - static inline ImVec2 GetItemBoxMin() { return GetItemRectMin(); } // OBSOLETE 1.36+ - static inline ImVec2 GetItemBoxMax() { return GetItemRectMax(); } // OBSOLETE 1.36+ - static inline bool IsClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.38+ - static inline bool IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+ - static inline bool IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); } // OBSOLETE 1.36+ static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETE 1.42+ + static inline bool GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); } // OBSOLETE 1.39+ + static inline bool IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+ #endif } // namespace ImGui diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp index 67846e7ab1b..b6582a88a69 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp @@ -2184,7 +2184,8 @@ struct ExampleAppConsole } else if (Stricmp(command_line, "HISTORY") == 0) { - for (int i = History.Size >= 10 ? History.Size - 10 : 0; i < History.Size; i++) + int first = History.Size - 10; + for (int i = first > 0 ? first : 0; i < History.Size; i++) AddLog("%3d: %s\n", i, History[i]); } else diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h index 7b59bb63f66..dc02f719a63 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h @@ -703,9 +703,6 @@ namespace ImGui IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing); - inline IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul) { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * alpha_mul; return ImGui::ColorConvertFloat4ToU32(c); } - inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); } - // NB: All position are in absolute pixels coordinates (not window coordinates) // FIXME: All those functions are a mess and needs to be refactored into something decent. Avoid use outside of imgui.cpp! // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers. diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_wm.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_wm.cpp index ac584ce110c..83a7e40d376 100644 --- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_wm.cpp +++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_wm.cpp @@ -575,8 +575,8 @@ namespace ImGuiWM ImColor oSelectedTab(37, 37, 37, 255); // selected ImColor oBorderColor(72, 72, 72, 255); // border - ImVec2 oRectMin = ImGui::GetItemBoxMin(); - ImVec2 oRectMax = ImGui::GetItemBoxMax(); + ImVec2 oRectMin = ImGui::GetItemRectMin(); + ImVec2 oRectMax = ImGui::GetItemRectMax(); const float fOverlap = 10.f; const float fSlopWidth = 30.f; diff --git a/3rdparty/bgfx/examples/common/imgui/imgui.cpp b/3rdparty/bgfx/examples/common/imgui/imgui.cpp index b8bf5b97a39..6a80447a34b 100644 --- a/3rdparty/bgfx/examples/common/imgui/imgui.cpp +++ b/3rdparty/bgfx/examples/common/imgui/imgui.cpp @@ -1488,7 +1488,7 @@ struct Imgui } } - uint8_t tabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint8_t _nTabs, uint8_t _nEnabled, va_list _argList) + uint8_t tabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint32_t _nTabs, uint32_t _nEnabled, va_list _argList) { const char* titles[16]; bool tabEnabled[16]; @@ -3469,7 +3469,7 @@ void imguiInput(const char* _label, char* _str, uint32_t _len, bool _enabled, Im s_imgui.input(_label, _str, _len, _enabled, _align, _r); } -uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint8_t _nTabs, uint8_t _nEnabled, ...) +uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint32_t _nTabs, uint32_t _nEnabled, ...) { va_list argList; va_start(argList, _nEnabled); @@ -3479,7 +3479,7 @@ uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int return result; } -uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint8_t _nTabs, ...) +uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint32_t _nTabs, ...) { va_list argList; va_start(argList, _nTabs); diff --git a/3rdparty/bgfx/examples/common/imgui/imgui.h b/3rdparty/bgfx/examples/common/imgui/imgui.h index 273f2a817e7..3b0fc54f875 100644 --- a/3rdparty/bgfx/examples/common/imgui/imgui.h +++ b/3rdparty/bgfx/examples/common/imgui/imgui.h @@ -190,8 +190,8 @@ void imguiInput(const char* _label, char* _str, uint32_t _len, bool _enabled = t /// _nEnabled - Number of specified 'enabled' flags. All other unspecified tabs are considered enabled by default. /// In the above example, there are 2 enabled flags: 'Tab0' is specified as enabled and 'Tab1' is specified as disabled. /// Tab2 is unspecified and therefore is treated as enabled. -uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint8_t _nTabs, uint8_t _nEnabled, ...); -uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint8_t _nTabs, ...); +uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint32_t _nTabs, uint32_t _nEnabled, ...); +uint8_t imguiTabs(uint8_t _selected, bool _enabled, ImguiAlign::Enum _align, int32_t _height, int32_t _r, uint32_t _nTabs, ...); uint32_t imguiChooseUseMacroInstead(uint32_t _selected, ...); #define imguiChoose(...) imguiChooseUseMacroInstead(__VA_ARGS__, NULL) diff --git a/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.cpp b/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.cpp index 41095d853bb..05973f26284 100644 --- a/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.cpp +++ b/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.cpp @@ -548,6 +548,7 @@ namespace static void nvgRenderViewport(void* _userPtr, int width, int height, float devicePixelRatio) { struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; + gl->state = 0; gl->view[0] = (float)width; gl->view[1] = (float)height; bgfx::setViewRect(gl->m_viewId, 0, 0, width * devicePixelRatio, height * devicePixelRatio); @@ -714,33 +715,24 @@ namespace int allocated = gl->tvb.size/gl->tvb.stride; - if (allocated < gl->nverts) { + if (allocated < gl->nverts) + { gl->nverts = allocated; BX_WARN(true, "Vertex number truncated due to transient vertex buffer overflow"); } - memcpy(gl->tvb.data, gl->verts, gl->nverts * sizeof(struct NVGvertex) ); - gl->state = 0 + if (0 == gl->state) + { + gl->state = BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA); + } + + gl->state |= 0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE ; -// if (alphaBlend == NVG_PREMULTIPLIED_ALPHA) -// { -// gl->state |= BGFX_STATE_BLEND_FUNC_SEPARATE( -// BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA -// , BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_INV_SRC_ALPHA -// ); -// } -// else - { - gl->state |= BGFX_STATE_BLEND_FUNC( - BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA - ); - } - bgfx::setUniform(gl->u_viewSize, gl->view); for (uint32_t ii = 0, num = gl->ncalls; ii < num; ++ii) @@ -1089,7 +1081,26 @@ error: } NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId) { - return nvgCreate(edgeaa, _viewId, NULL); + return nvgCreate(edgeaa, _viewId, NULL); +} + +void nvgDelete(struct NVGcontext* ctx) +{ + nvgDeleteInternal(ctx); +} + +void nvgState(struct NVGcontext* ctx, uint64_t state) +{ + struct NVGparams* params = nvgInternalParams(ctx); + struct GLNVGcontext* gl = (struct GLNVGcontext*)params->userPtr; + gl->state = state; +} + +uint8_t nvgViewId(struct NVGcontext* ctx) +{ + struct NVGparams* params = nvgInternalParams(ctx); + struct GLNVGcontext* gl = (struct GLNVGcontext*)params->userPtr; + return gl->m_viewId; } void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId) @@ -1099,7 +1110,55 @@ void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId) gl->m_viewId = uint8_t(_viewId); } -void nvgDelete(struct NVGcontext* ctx) +bgfx::TextureHandle nvglImageHandle(NVGcontext* ctx, int image) { - nvgDeleteInternal(ctx); + GLNVGcontext* gl = (GLNVGcontext*)nvgInternalParams(ctx)->userPtr; + GLNVGtexture* tex = glnvg__findTexture(gl, image); + return tex->id; +} + +NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int width, + int height, int imageFlags) { + NVGLUframebuffer* framebuffer = new NVGLUframebuffer; + framebuffer->ctx = ctx; + framebuffer->image = nvgCreateImageRGBA(ctx, width, height, + imageFlags, NULL); + bgfx::TextureHandle texture = nvglImageHandle(ctx, framebuffer->image); + if (!bgfx::isValid(texture)) { + nvgluDeleteFramebuffer(framebuffer); + return NULL; + } + framebuffer->handle = bgfx::createFrameBuffer(1, &texture, false); + if (!bgfx::isValid(framebuffer->handle)) + { + nvgluDeleteFramebuffer(framebuffer); + return NULL; + } + static uint8_t s_ViewId = 1; // may have a better way to assign new view id + framebuffer->viewId = s_ViewId++; + bgfx::setViewFrameBuffer(framebuffer->viewId, framebuffer->handle); + bgfx::setViewSeq(framebuffer->viewId, true); + return framebuffer; +} + +void nvgluBindFramebuffer(NVGLUframebuffer* framebuffer) { + static NVGcontext* s_prevCtx = NULL; + static uint8_t s_prevViewId; + if (framebuffer != NULL) { + s_prevCtx = framebuffer->ctx; + s_prevViewId = nvgViewId(framebuffer->ctx); + nvgViewId(framebuffer->ctx, framebuffer->viewId); + } else if (s_prevCtx != NULL) { + nvgViewId(s_prevCtx, s_prevViewId); + } +} + +void nvgluDeleteFramebuffer(NVGLUframebuffer* framebuffer) { + if (framebuffer == NULL) + return; + if (framebuffer->image >= 0) + nvgDeleteImage(framebuffer->ctx, framebuffer->image); + if (bgfx::isValid(framebuffer->handle)) + bgfx::destroyFrameBuffer(framebuffer->handle); + delete framebuffer; } diff --git a/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.h b/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.h index d24ee4fa72f..2268e900f99 100644 --- a/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.h +++ b/3rdparty/bgfx/examples/common/nanovg/nanovg_bgfx.h @@ -6,13 +6,47 @@ #ifndef NANOVG_BGFX_H_HEADER_GUARD #define NANOVG_BGFX_H_HEADER_GUARD +#include "bgfx/bgfx.h" + namespace bx { struct AllocatorI; } struct NVGcontext; +struct NVGLUframebuffer { + NVGcontext* ctx; + bgfx::FrameBufferHandle handle; + int image; + uint8_t viewId; +}; +typedef struct NVGLUframebuffer NVGLUframebuffer; + NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId, bx::AllocatorI* _allocator); NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId); -void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId); void nvgDelete(struct NVGcontext* ctx); +void nvgState(struct NVGcontext* ctx, uint64_t state); +uint8_t nvgViewId(struct NVGcontext* ctx); +void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId); + +// Helper functions to create bgfx framebuffer to render to. +// Example: +// float scale = 2; +// NVGLUframebuffer* fb = nvgluCreateFramebuffer(ctx, 100 * scale, 100 * scale, 0); +// nvgluBindFramebuffer(fb); +// nvgBeginFrame(ctx, 100, 100, scale); +// // renders anything offscreen +// nvgEndFrame(ctx); +// nvgluBindFramebuffer(NULL); +// +// // Pastes the framebuffer rendering. +// nvgBeginFrame(ctx, 1024, 768, scale); +// NVGpaint paint = nvgImagePattern(ctx, 0, 0, 100, 100, 0, fb->image, 1); +// nvgBeginPath(ctx); +// nvgRect(ctx, 0, 0, 100, 100); +// nvgFillPaint(ctx, paint); +// nvgFill(ctx); +// nvgEndFrame(ctx); +NVGLUframebuffer* nvgluCreateFramebuffer(NVGcontext* ctx, int width, int height, int imageFlags); +void nvgluBindFramebuffer(NVGLUframebuffer* framebuffer); +void nvgluDeleteFramebuffer(NVGLUframebuffer* framebuffer); #endif // NANOVG_BGFX_H_HEADER_GUARD diff --git a/3rdparty/bgfx/src/renderer_mtl.h b/3rdparty/bgfx/src/renderer_mtl.h index 42145e0c036..13f1bf6b7af 100644 --- a/3rdparty/bgfx/src/renderer_mtl.h +++ b/3rdparty/bgfx/src/renderer_mtl.h @@ -87,6 +87,16 @@ namespace bgfx { namespace mtl destinationSlice:_destinationSlice destinationLevel:_destinationLevel destinationOrigin:_destinationOrigin]; } + void synchronizeTexture(id _texture, NSUInteger _slice, NSUInteger _level) + { + [m_obj synchronizeTexture:_texture slice:_slice level:_level]; + } + + void synchronizeResource(id _resource) + { + [m_obj synchronizeResource:_resource]; + } + void endEncoding() { [m_obj endEncoding]; diff --git a/3rdparty/bgfx/src/renderer_mtl.mm b/3rdparty/bgfx/src/renderer_mtl.mm index b2dcdd36900..ce2bf3b8b51 100644 --- a/3rdparty/bgfx/src/renderer_mtl.mm +++ b/3rdparty/bgfx/src/renderer_mtl.mm @@ -3023,16 +3023,23 @@ namespace bgfx { namespace mtl uint32_t width = bx::uint32_min(srcWidth, dstWidth); uint32_t height = bx::uint32_min(srcHeight, dstHeight); uint32_t depth = bx::uint32_min(srcDepth, dstDepth); + bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK); if ( MTLTextureType3D == src.m_ptr.textureType()) { m_blitCommandEncoder.copyFromTexture(src.m_ptr, 0, 0, MTLOriginMake(blit.m_srcX, blit.m_srcY, blit.m_srcZ), MTLSizeMake(width, height, bx::uint32_imax(depth, 1)), dst.m_ptr, 0, 0, MTLOriginMake(blit.m_dstX, blit.m_dstY, blit.m_dstZ)); + if (m_macOS11Runtime &&readBack) { + m_blitCommandEncoder.synchronizeResource(dst.m_ptr); + } } else { m_blitCommandEncoder.copyFromTexture(src.m_ptr, blit.m_srcZ, blit.m_srcMip, MTLOriginMake(blit.m_srcX, blit.m_srcY, 0), MTLSizeMake(width, height, 1), dst.m_ptr, blit.m_dstZ, blit.m_dstMip, MTLOriginMake(blit.m_dstX, blit.m_dstY, 0)); + if (m_macOS11Runtime && readBack) { + m_blitCommandEncoder.synchronizeTexture(dst.m_ptr, 0, blit.m_dstMip); + } } }