Optimize UITextEdit rendering

This commit is contained in:
Konrad Kuśnierz 2015-06-03 14:56:43 +02:00
parent 559e545e36
commit 6893a5e98a
7 changed files with 48 additions and 22 deletions

View File

@ -135,6 +135,12 @@ void PainterOGL1::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
#endif #endif
} }
void PainterOGL1::drawFillCoords(CoordsBuffer& coordsBuffer)
{
setTexture(nullptr);
drawCoords(coordsBuffer);
}
void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
{ {
if(texture->isEmpty()) if(texture->isEmpty())

View File

@ -50,6 +50,7 @@ public:
void refreshState(); void refreshState();
void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles); void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
void drawFillCoords(CoordsBuffer& coordsBuffer);
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture); void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);

View File

@ -120,6 +120,13 @@ void PainterOGL2::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
PainterShaderProgram::enableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR); PainterShaderProgram::enableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR);
} }
void PainterOGL2::drawFillCoords(CoordsBuffer& coordsBuffer)
{
setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawSolidColorProgram.get());
setTexture(nullptr);
drawCoords(coordsBuffer);
}
void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
{ {
if(texture && texture->isEmpty()) if(texture && texture->isEmpty())

View File

@ -41,6 +41,7 @@ public:
void unbind(); void unbind();
void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles); void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
void drawFillCoords(CoordsBuffer& coordsBuffer);
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture); void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); void drawUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);

View File

@ -62,6 +62,7 @@ public:
virtual void clear(const Color& color) = 0; virtual void clear(const Color& color) = 0;
virtual void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0; virtual void drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles) = 0;
virtual void drawFillCoords(CoordsBuffer& coordsBuffer) = 0;
virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0; virtual void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) = 0;
virtual void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0; virtual void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) = 0;
void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); } void drawTexturedRect(const Rect& dest, const TexturePtr& texture) { drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); }

View File

@ -49,6 +49,9 @@ UITextEdit::UITextEdit()
m_updatesEnabled = true; m_updatesEnabled = true;
m_selectionColor = Color::white; m_selectionColor = Color::white;
m_selectionBackgroundColor = Color::black; m_selectionBackgroundColor = Color::black;
m_glyphsTextCoordsBuffer.enableHardwareCaching();
m_glyphsSelectCoordsBuffer.enableHardwareCaching();
m_glyphsMustRecache = true;
blinkCursor(); blinkCursor();
} }
@ -62,38 +65,36 @@ void UITextEdit::drawSelf(Fw::DrawPane drawPane)
drawImage(m_rect); drawImage(m_rect);
drawIcon(m_rect); drawIcon(m_rect);
//TODO: text rendering could be much optimized by using vertex buffer or caching the render into a texture
int textLength = m_text.length(); int textLength = m_text.length();
const TexturePtr& texture = m_font->getTexture(); const TexturePtr& texture = m_font->getTexture();
if(!texture) if(!texture)
return; return;
if(hasSelection()) { bool glyphsMustRecache = m_glyphsMustRecache;
if(m_color != Color::alpha) { if(glyphsMustRecache)
g_painter->setColor(m_color); m_glyphsMustRecache = false;
for(int i=0;i<m_selectionStart;++i)
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
}
for(int i=m_selectionStart;i<m_selectionEnd;++i) {
g_painter->setColor(m_selectionBackgroundColor);
g_painter->drawFilledRect(m_glyphsCoords[i]);
g_painter->setColor(m_selectionColor);
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
}
if(m_color != Color::alpha) { if(m_color != Color::alpha) {
g_painter->setColor(m_color); if(glyphsMustRecache) {
for(int i=m_selectionEnd;i<textLength;++i) m_glyphsTextCoordsBuffer.clear();
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
}
} else if(m_color != Color::alpha) {
g_painter->setColor(m_color);
for(int i=0;i<textLength;++i) for(int i=0;i<textLength;++i)
g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]); m_glyphsTextCoordsBuffer.addRect(m_glyphsCoords[i], m_glyphsTexCoords[i]);
}
g_painter->setColor(m_color);
g_painter->drawTextureCoords(m_glyphsTextCoordsBuffer, texture);
} }
if(hasSelection()) {
if(glyphsMustRecache) {
m_glyphsSelectCoordsBuffer.clear();
for(int i=m_selectionStart;i<m_selectionEnd;++i)
m_glyphsSelectCoordsBuffer.addRect(m_glyphsCoords[i], m_glyphsTexCoords[i]);
}
g_painter->setColor(m_selectionBackgroundColor);
g_painter->drawFillCoords(m_glyphsSelectCoordsBuffer);
g_painter->setColor(m_selectionColor);
g_painter->drawTextureCoords(m_glyphsSelectCoordsBuffer, texture);
}
// render cursor // render cursor
if(isExplicitlyEnabled() && m_cursorVisible && m_cursorInRange && isActive() && m_cursorPos >= 0) { if(isExplicitlyEnabled() && m_cursorVisible && m_cursorInRange && isActive() && m_cursorPos >= 0) {
@ -136,6 +137,9 @@ void UITextEdit::update(bool focusCursor)
if(m_rect.isEmpty()) if(m_rect.isEmpty())
return; return;
// recache coords buffers
recacheGlyphs();
// map glyphs positions // map glyphs positions
Size textBoxSize; Size textBoxSize;
const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize); const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
@ -360,6 +364,7 @@ void UITextEdit::setSelection(int start, int end)
m_selectionStart = stdext::clamp<int>(start, 0, (int)m_text.length()); m_selectionStart = stdext::clamp<int>(start, 0, (int)m_text.length());
m_selectionEnd = stdext::clamp<int>(end, 0, (int)m_text.length()); m_selectionEnd = stdext::clamp<int>(end, 0, (int)m_text.length());
recacheGlyphs();
} }
void UITextEdit::setTextHidden(bool hidden) void UITextEdit::setTextHidden(bool hidden)

View File

@ -108,6 +108,7 @@ protected:
private: private:
void disableUpdates() { m_updatesEnabled = false; } void disableUpdates() { m_updatesEnabled = false; }
void enableUpdates() { m_updatesEnabled = true; } void enableUpdates() { m_updatesEnabled = true; }
void recacheGlyphs() { m_glyphsMustRecache = true; }
Rect m_drawArea; Rect m_drawArea;
int m_cursorPos; int m_cursorPos;
@ -137,6 +138,10 @@ private:
std::vector<Rect> m_glyphsCoords; std::vector<Rect> m_glyphsCoords;
std::vector<Rect> m_glyphsTexCoords; std::vector<Rect> m_glyphsTexCoords;
CoordsBuffer m_glyphsTextCoordsBuffer;
CoordsBuffer m_glyphsSelectCoordsBuffer;
bool m_glyphsMustRecache;
}; };
#endif #endif