void FontRendererImpl::DrawPerFrame() { m_mutex.lock(); for (auto& renderable : m_queuedRenderables) { renderable->Render(); } m_queuedRenderables.clear(); FrpSeqAllocatorSwapPage(); m_gameInterface->InvokeOnRender([] (void* arg) { FrpSeqAllocatorUnlockSwap(); }, nullptr); // clean the layout cache if needed // TODO: keep layouts for longer if they actually get recently used if ((GetTickCount() - m_lastLayoutClean) > 5000) { m_textLayoutCache.clear(); m_lastLayoutClean = GetTickCount(); } m_mutex.unlock(); }
void FontRendererImpl::DrawPerFrame() { m_mutex.lock(); // draw rectangles auto numRectangles = m_queuedRectangles.size(); if (numRectangles) { // allocate a structure ResultingRectangles* rectangles = new ResultingRectangles(); rectangles->count = numRectangles; rectangles->rectangles = new ResultingRectangle[numRectangles]; // copy to output std::copy(m_queuedRectangles.begin(), m_queuedRectangles.end(), rectangles->rectangles); m_gameInterface->InvokeOnRender([] (void* arg) { auto rectangles = (ResultingRectangles*)arg; g_fontRenderer.GetGameInterface()->DrawRectangles(rectangles->count, rectangles->rectangles); delete[] rectangles->rectangles; delete rectangles; }, rectangles); m_queuedRectangles.clear(); } // draw glyph runs auto numRuns = m_queuedGlyphRuns.size(); if (numRuns) { ResultingGlyphRun** glyphRuns = new ResultingGlyphRun*[numRuns + 1]; memcpy(glyphRuns, &m_queuedGlyphRuns[0], sizeof(ResultingGlyphRun*) * numRuns); glyphRuns[numRuns] = nullptr; m_gameInterface->InvokeOnRender([] (void* arg) { auto glyphRuns = (ResultingGlyphRun**)arg; for (ResultingGlyphRun** p = glyphRuns; *p; p++) { auto glyphRun = *p; for (uint32_t i = 0; i < glyphRun->numSubRuns; i++) { auto subRun = &glyphRun->subRuns[i]; g_fontRenderer.GetGameInterface()->SetTexture(subRun->texture); g_fontRenderer.GetGameInterface()->DrawIndexedVertices(subRun->numVertices, subRun->numIndices, subRun->vertices, subRun->indices); g_fontRenderer.GetGameInterface()->UnsetTexture(); } delete glyphRun; } delete glyphRuns; }, glyphRuns); m_queuedGlyphRuns.clear(); } FrpSeqAllocatorSwapPage(); m_gameInterface->InvokeOnRender([] (void* arg) { FrpSeqAllocatorUnlockSwap(); }, nullptr); // clean the layout cache if needed // TODO: keep layouts for longer if they actually get recently used if ((GetTickCount() - m_lastLayoutClean) > 5000) { m_textLayoutCache.clear(); m_lastLayoutClean = GetTickCount(); } m_mutex.unlock(); }