mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-10 06:18:57 -05:00
GLFont temporary string compiling/caching with garbage collect
This commit is contained in:
parent
cfdbcf9bc3
commit
297e35ebf7
@ -254,7 +254,7 @@ void SpectrumPanel::drawPanelContents() {
|
||||
|
||||
glColor4f(ThemeMgr::mgr.currentTheme->text.r, ThemeMgr::mgr.currentTheme->text.g, ThemeMgr::mgr.currentTheme->text.b,1.0);
|
||||
|
||||
GLFont::getFont(fontEnumSize).drawString(label.str(), m, hPos, fontSize, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(fontEnumSize).drawString(label.str(), m, hPos, fontSize, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
|
||||
label.str(std::string());
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include "cubic_math.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <windows.h>
|
||||
@ -27,6 +29,9 @@ static std::string getExePath(void)
|
||||
#define RES_FOLDER ""
|
||||
#endif
|
||||
|
||||
GLFontStringCache::GLFontStringCache() {
|
||||
gc = 0;
|
||||
}
|
||||
|
||||
GLFont GLFont::fonts[GLFONT_MAX];
|
||||
|
||||
@ -122,7 +127,7 @@ int GLFontChar::getIndex() {
|
||||
}
|
||||
|
||||
GLFont::GLFont() :
|
||||
lineHeight(0), base(0), imageWidth(0), imageHeight(0), loaded(false), texId(0) {
|
||||
lineHeight(0), base(0), imageWidth(0), imageHeight(0), loaded(false), texId(0), gcCounter(0) {
|
||||
|
||||
}
|
||||
|
||||
@ -423,11 +428,11 @@ float GLFont::getStringWidth(std::string str, float size, float viewAspect) {
|
||||
return width;
|
||||
}
|
||||
|
||||
void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, Align hAlign, Align vAlign, int vpx, int vpy) {
|
||||
|
||||
|
||||
// Draw string, immediate
|
||||
void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, Align hAlign, Align vAlign, int vpx, int vpy, bool cacheable) {
|
||||
|
||||
pxHeight *= 2;
|
||||
|
||||
|
||||
if (!vpx || !vpy) {
|
||||
GLint vp[4];
|
||||
glGetIntegerv( GL_VIEWPORT, vp);
|
||||
@ -435,6 +440,49 @@ void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, A
|
||||
vpy = vp[3];
|
||||
}
|
||||
|
||||
if (cacheable) {
|
||||
gcCounter++;
|
||||
|
||||
std::lock_guard<std::mutex> lock(cache_busy);
|
||||
|
||||
if (gcCounter > 200) {
|
||||
doCacheGC();
|
||||
gcCounter = 0;
|
||||
}
|
||||
|
||||
GLFontStringCache *fc = nullptr;
|
||||
|
||||
std::map<int, std::map<int, std::map<int, std::map<std::string, GLFontStringCache * > > > >::iterator i1;
|
||||
std::map<int, std::map<int, std::map<std::string, GLFontStringCache * > > >::iterator i2;
|
||||
std::map<int, std::map<std::string, GLFontStringCache * > >::iterator i3;
|
||||
std::map<std::string, GLFontStringCache * >::iterator i4;
|
||||
|
||||
i1 = stringCache.find(vpx);
|
||||
if (i1 != stringCache.end()) {
|
||||
i2 = i1->second.find(vpy);
|
||||
if (i2 != i1->second.end()) {
|
||||
i3 = i2->second.find(pxHeight);
|
||||
if (i3 != i2->second.end()) {
|
||||
i4 = i3->second.find(str);
|
||||
if (i4 != i3->second.end()) {
|
||||
fc = i4->second;
|
||||
fc->gc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fc == nullptr) {
|
||||
// std::cout << "cache miss" << std::endl;
|
||||
fc = cacheString(str, pxHeight, vpx, vpy);
|
||||
stringCache[vpx][vpy][pxHeight][str] = fc;
|
||||
}
|
||||
|
||||
drawCacheString(fc, xpos, ypos, hAlign, vAlign);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
float size = (float) pxHeight / (float) vpy;
|
||||
float viewAspect = (float) vpx / (float) vpy;
|
||||
float msgWidth = getStringWidth(str, size, viewAspect);
|
||||
@ -499,6 +547,9 @@ void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, A
|
||||
glTranslatef(fchar->getAspect() + advx, 0.0, 0.0);
|
||||
}
|
||||
|
||||
glVertexPointer(2, GL_FLOAT, 0, nullptr);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, nullptr);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glPopMatrix();
|
||||
@ -508,6 +559,157 @@ void GLFont::drawString(std::string str, float xpos, float ypos, int pxHeight, A
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// Draw cached GLFontCacheString
|
||||
void GLFont::drawCacheString(GLFontStringCache *fc, float xpos, float ypos, Align hAlign, Align vAlign) {
|
||||
|
||||
float size = (float) fc->pxHeight / (float) fc->vpy;
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(xpos, ypos, 0.0f);
|
||||
|
||||
switch (vAlign) {
|
||||
case GLFONT_ALIGN_TOP:
|
||||
glTranslatef(0.0, -size, 0.0);
|
||||
break;
|
||||
case GLFONT_ALIGN_CENTER:
|
||||
glTranslatef(0.0, -size/2.0, 0.0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (hAlign) {
|
||||
case GLFONT_ALIGN_RIGHT:
|
||||
glTranslatef(-fc->msgWidth, 0.0, 0.0);
|
||||
break;
|
||||
case GLFONT_ALIGN_CENTER:
|
||||
glTranslatef(-fc->msgWidth / 2.0, 0.0, 0.0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glVertexPointer(2, GL_FLOAT, 0, &fc->gl_vertices[0]);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, &fc->gl_uv[0]);
|
||||
|
||||
glDrawArrays(GL_QUADS, 0, 4 * fc->drawlen);
|
||||
|
||||
glVertexPointer(2, GL_FLOAT, 0, nullptr);
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, nullptr);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// Compile optimized GLFontCacheString
|
||||
GLFontStringCache *GLFont::cacheString(std::string str, int pxHeight, int vpx, int vpy) {
|
||||
GLFontStringCache *fc = new GLFontStringCache;
|
||||
|
||||
fc->pxHeight = pxHeight;
|
||||
fc->vpx = vpx;
|
||||
fc->vpy = vpy;
|
||||
|
||||
float size = (float) pxHeight / (float) vpy;
|
||||
float viewAspect = (float) vpx / (float) vpy;
|
||||
|
||||
fc->msgWidth = getStringWidth(str, size, viewAspect);
|
||||
|
||||
int nChar = 0;
|
||||
for (int i = 0, iMax = str.length(); i < iMax; i++) {
|
||||
int charId = str.at(i);
|
||||
|
||||
if (characters.find(charId) == characters.end()) {
|
||||
continue;
|
||||
}
|
||||
nChar++;
|
||||
}
|
||||
|
||||
fc->drawlen = nChar;
|
||||
fc->gl_vertices.resize(nChar*8);
|
||||
fc->gl_uv.resize(nChar*8);
|
||||
|
||||
|
||||
CubicVR::mat4 trans = CubicVR::mat4::scale(size / viewAspect, size, 1.0f);
|
||||
|
||||
int c = 0;
|
||||
for (int i = 0, iMax = str.length(); i < iMax; i++) {
|
||||
int charId = str.at(i);
|
||||
|
||||
if (characters.find(charId) == characters.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GLFontChar *fchar = characters[charId];
|
||||
|
||||
float ofsx = (float) fchar->getXOffset() / (float) imageWidth;
|
||||
float advx = (float) fchar->getXAdvance() / (float) imageWidth;
|
||||
|
||||
if (charId == 32) {
|
||||
advx = characters['_']->getAspect();
|
||||
}
|
||||
|
||||
// freeze transform to buffer
|
||||
trans *= CubicVR::mat4::translate(ofsx, 0.0, 0.0);
|
||||
int charIdx = fchar->getIndex();
|
||||
for (int j = 0; j < 8; j+=2) {
|
||||
CubicVR::vec3 pt(gl_vertices[charIdx + j],gl_vertices[charIdx + j + 1], 0.0);
|
||||
pt = CubicVR::mat4::multiply(trans, pt, true);
|
||||
fc->gl_vertices[c * 8 + j] = pt[0];
|
||||
fc->gl_vertices[c * 8 + j + 1] = pt[1];
|
||||
fc->gl_uv[c * 8 + j] = gl_uv[charIdx + j];
|
||||
fc->gl_uv[c * 8 + j + 1] = gl_uv[charIdx + j + 1];
|
||||
}
|
||||
trans *= CubicVR::mat4::translate(fchar->getAspect() + advx, 0.0, 0.0);
|
||||
c++;
|
||||
}
|
||||
|
||||
return fc;
|
||||
}
|
||||
|
||||
void GLFont::doCacheGC() {
|
||||
std::map<int, std::map<int, std::map<int, std::map<std::string, GLFontStringCache * > > > >::iterator i1;
|
||||
std::map<int, std::map<int, std::map<std::string, GLFontStringCache * > > >::iterator i2;
|
||||
std::map<int, std::map<std::string, GLFontStringCache * > >::iterator i3;
|
||||
std::map<std::string, GLFontStringCache * >::iterator i4;
|
||||
|
||||
std::vector<std::map<std::string, GLFontStringCache * >::iterator> removals;
|
||||
std::vector<std::map<std::string, GLFontStringCache * >::iterator>::iterator removals_i;
|
||||
|
||||
for (i1 = stringCache.begin(); i1 != stringCache.end(); i1++) {
|
||||
for (i2 = i1->second.begin(); i2 != i1->second.end(); i2++) {
|
||||
for (i3 = i2->second.begin(); i3 != i2->second.end(); i3++) {
|
||||
for (i4 = i3->second.begin(); i4 != i3->second.end(); i4++) {
|
||||
i4->second->gc--;
|
||||
if (i4->second->gc < -10) {
|
||||
removals.push_back(i4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (removals.size()) {
|
||||
for (removals_i = removals.begin(); removals_i != removals.end(); removals_i++) {
|
||||
// std::cout << "gc'd " << (*removals_i)->first << std::endl;
|
||||
GLFontStringCache *fc = (*removals_i)->second;
|
||||
stringCache[fc->vpx][fc->vpy][fc->pxHeight].erase(*removals_i);
|
||||
delete (*removals_i)->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GLFont &GLFont::getFont(GLFontSize esize) {
|
||||
|
@ -8,6 +8,18 @@
|
||||
#include "wx/filename.h"
|
||||
#include "wx/stdpaths.h"
|
||||
|
||||
class GLFontStringCache {
|
||||
public:
|
||||
GLFontStringCache();
|
||||
int drawlen;
|
||||
int vpx, vpy;
|
||||
int pxHeight;
|
||||
float msgWidth;
|
||||
int gc;
|
||||
std::vector<float> gl_vertices;
|
||||
std::vector<float> gl_uv;
|
||||
};
|
||||
|
||||
class GLFontChar {
|
||||
public:
|
||||
GLFontChar();
|
||||
@ -66,12 +78,18 @@ public:
|
||||
bool isLoaded();
|
||||
|
||||
float getStringWidth(std::string str, float size, float viewAspect);
|
||||
void drawString(std::string str, float xpos, float ypos, int pxHeight, Align hAlign = GLFONT_ALIGN_LEFT, Align vAlign = GLFONT_ALIGN_TOP, int vpx=0, int vpy=0);
|
||||
void drawString(std::string str, float xpos, float ypos, int pxHeight, Align hAlign = GLFONT_ALIGN_LEFT, Align vAlign = GLFONT_ALIGN_TOP, int vpx=0, int vpy=0, bool cacheable = false);
|
||||
|
||||
static GLFont fonts[GLFONT_MAX];
|
||||
static GLFont &getFont(GLFontSize esize);
|
||||
|
||||
GLFontStringCache *cacheString(std::string str, int pxHeight, int vpx, int vpy);
|
||||
void drawCacheString(GLFontStringCache *fc, float xpos, float ypos, Align hAlign, Align vAlign);
|
||||
|
||||
void doCacheGC();
|
||||
private:
|
||||
std::map<int, std::map<int, std::map<int, std::map<std::string, GLFontStringCache * > > > > stringCache;
|
||||
|
||||
std::string nextParam(std::istringstream &str);
|
||||
std::string getParamKey(std::string param_str);
|
||||
std::string getParamValue(std::string param_str);
|
||||
@ -90,4 +108,6 @@ private:
|
||||
std::string imageFile;
|
||||
std::string fontFileSource;
|
||||
GLuint texId;
|
||||
int gcCounter;
|
||||
std::mutex cache_busy;
|
||||
};
|
||||
|
@ -166,11 +166,11 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGBA4f color, l
|
||||
}
|
||||
|
||||
if (demod->getDemodulatorType() == "USB") {
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_LEFT, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_LEFT, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
} else if (demod->getDemodulatorType() == "LSB") {
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
} else {
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodLabel, uxPos, hPos, 16, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
}
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
@ -381,9 +381,9 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGBA4f color, long
|
||||
|
||||
glColor3f(0, 0, 0);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5) + xOfs, -1.0 + hPos - yOfs, 16, demodAlign,
|
||||
GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
glColor3f(1, 1, 1);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5), -1.0 + hPos, 16, demodAlign, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE16).drawString(demodStr, 2.0 * (uxPos - 0.5), -1.0 + hPos, 16, demodAlign, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
|
@ -35,9 +35,9 @@ void ScopeContext::DrawTunerTitles(bool ppmMode) {
|
||||
|
||||
glColor3f(0.65, 0.65, 0.65);
|
||||
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(ppmMode?"Device PPM":"Frequency", -0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString("Bandwidth", 0.0, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString("Center Frequency", 0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(ppmMode?"Device PPM":"Frequency", -0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString("Bandwidth", 0.0, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString("Center Frequency", 0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
}
|
||||
|
||||
void ScopeContext::DrawDeviceName(std::string deviceName) {
|
||||
@ -47,7 +47,7 @@ void ScopeContext::DrawDeviceName(std::string deviceName) {
|
||||
float hPos = (float) (viewHeight - 20) / viewHeight;
|
||||
|
||||
glColor3f(0.65, 0.65, 0.65);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(deviceName.c_str(), 1.0, hPos, 12, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER);
|
||||
GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(deviceName.c_str(), 1.0, hPos, 12, GLFont::GLFONT_ALIGN_RIGHT, GLFont::GLFONT_ALIGN_CENTER, 0, 0, true);
|
||||
}
|
||||
|
||||
void ScopeContext::DrawEnd() {
|
||||
|
Loading…
Reference in New Issue
Block a user