Browse Source

Optimize UITextEdit rendering

Konrad Kuśnierz 5 years ago
parent
commit
6893a5e98a

+ 6
- 0
src/framework/graphics/ogl/painterogl1.cpp View File

@@ -135,6 +135,12 @@ void PainterOGL1::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
135 135
 #endif
136 136
 }
137 137
 
138
+void PainterOGL1::drawFillCoords(CoordsBuffer& coordsBuffer)
139
+{
140
+    setTexture(nullptr);
141
+    drawCoords(coordsBuffer);
142
+}
143
+
138 144
 void PainterOGL1::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
139 145
 {
140 146
     if(texture->isEmpty())

+ 1
- 0
src/framework/graphics/ogl/painterogl1.h View File

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

+ 7
- 0
src/framework/graphics/ogl/painterogl2.cpp View File

@@ -120,6 +120,13 @@ void PainterOGL2::drawCoords(CoordsBuffer& coordsBuffer, DrawMode drawMode)
120 120
         PainterShaderProgram::enableAttributeArray(PainterShaderProgram::TEXCOORD_ATTR);
121 121
 }
122 122
 
123
+void PainterOGL2::drawFillCoords(CoordsBuffer& coordsBuffer)
124
+{
125
+    setDrawProgram(m_shaderProgram ? m_shaderProgram : m_drawSolidColorProgram.get());
126
+    setTexture(nullptr);
127
+    drawCoords(coordsBuffer);
128
+}
129
+
123 130
 void PainterOGL2::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
124 131
 {
125 132
     if(texture && texture->isEmpty())

+ 1
- 0
src/framework/graphics/ogl/painterogl2.h View File

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

+ 1
- 0
src/framework/graphics/painter.h View File

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

+ 27
- 22
src/framework/ui/uitextedit.cpp View File

@@ -49,6 +49,9 @@ UITextEdit::UITextEdit()
49 49
     m_updatesEnabled = true;
50 50
     m_selectionColor = Color::white;
51 51
     m_selectionBackgroundColor = Color::black;
52
+    m_glyphsTextCoordsBuffer.enableHardwareCaching();
53
+    m_glyphsSelectCoordsBuffer.enableHardwareCaching();
54
+    m_glyphsMustRecache = true;
52 55
     blinkCursor();
53 56
 }
54 57
 
@@ -62,38 +65,36 @@ void UITextEdit::drawSelf(Fw::DrawPane drawPane)
62 65
     drawImage(m_rect);
63 66
     drawIcon(m_rect);
64 67
 
65
-    //TODO: text rendering could be much optimized by using vertex buffer or caching the render into a texture
66
-
67 68
     int textLength = m_text.length();
68 69
     const TexturePtr& texture = m_font->getTexture();
69 70
     if(!texture)
70 71
         return;
71 72
 
72
-    if(hasSelection()) {
73
-        if(m_color != Color::alpha) {
74
-            g_painter->setColor(m_color);
75
-            for(int i=0;i<m_selectionStart;++i)
76
-                g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
77
-        }
78
-
79
-        for(int i=m_selectionStart;i<m_selectionEnd;++i) {
80
-            g_painter->setColor(m_selectionBackgroundColor);
81
-            g_painter->drawFilledRect(m_glyphsCoords[i]);
82
-            g_painter->setColor(m_selectionColor);
83
-            g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
84
-        }
73
+    bool glyphsMustRecache = m_glyphsMustRecache;
74
+    if(glyphsMustRecache)
75
+        m_glyphsMustRecache = false;
85 76
 
86
-        if(m_color != Color::alpha) {
87
-            g_painter->setColor(m_color);
88
-            for(int i=m_selectionEnd;i<textLength;++i)
89
-                g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
77
+    if(m_color != Color::alpha) {
78
+        if(glyphsMustRecache) {
79
+            m_glyphsTextCoordsBuffer.clear();
80
+            for(int i=0;i<textLength;++i)
81
+                m_glyphsTextCoordsBuffer.addRect(m_glyphsCoords[i], m_glyphsTexCoords[i]);
90 82
         }
91
-    } else if(m_color != Color::alpha) {
92 83
         g_painter->setColor(m_color);
93
-        for(int i=0;i<textLength;++i)
94
-            g_painter->drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
84
+        g_painter->drawTextureCoords(m_glyphsTextCoordsBuffer, texture);
95 85
     }
96 86
 
87
+    if(hasSelection()) {
88
+        if(glyphsMustRecache) {
89
+            m_glyphsSelectCoordsBuffer.clear();
90
+            for(int i=m_selectionStart;i<m_selectionEnd;++i)
91
+                m_glyphsSelectCoordsBuffer.addRect(m_glyphsCoords[i], m_glyphsTexCoords[i]);
92
+        }
93
+        g_painter->setColor(m_selectionBackgroundColor);
94
+        g_painter->drawFillCoords(m_glyphsSelectCoordsBuffer);
95
+        g_painter->setColor(m_selectionColor);
96
+        g_painter->drawTextureCoords(m_glyphsSelectCoordsBuffer, texture);
97
+    }
97 98
 
98 99
     // render cursor
99 100
     if(isExplicitlyEnabled() && m_cursorVisible && m_cursorInRange && isActive() && m_cursorPos >= 0) {
@@ -136,6 +137,9 @@ void UITextEdit::update(bool focusCursor)
136 137
     if(m_rect.isEmpty())
137 138
         return;
138 139
 
140
+    // recache coords buffers
141
+    recacheGlyphs();
142
+
139 143
     // map glyphs positions
140 144
     Size textBoxSize;
141 145
     const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize);
@@ -360,6 +364,7 @@ void UITextEdit::setSelection(int start, int end)
360 364
 
361 365
     m_selectionStart = stdext::clamp<int>(start, 0, (int)m_text.length());
362 366
     m_selectionEnd = stdext::clamp<int>(end, 0, (int)m_text.length());
367
+    recacheGlyphs();
363 368
 }
364 369
 
365 370
 void UITextEdit::setTextHidden(bool hidden)

+ 5
- 0
src/framework/ui/uitextedit.h View File

@@ -108,6 +108,7 @@ protected:
108 108
 private:
109 109
     void disableUpdates() { m_updatesEnabled = false; }
110 110
     void enableUpdates() { m_updatesEnabled = true; }
111
+    void recacheGlyphs() { m_glyphsMustRecache = true; }
111 112
 
112 113
     Rect m_drawArea;
113 114
     int m_cursorPos;
@@ -137,6 +138,10 @@ private:
137 138
 
138 139
     std::vector<Rect> m_glyphsCoords;
139 140
     std::vector<Rect> m_glyphsTexCoords;
141
+
142
+    CoordsBuffer m_glyphsTextCoordsBuffer;
143
+    CoordsBuffer m_glyphsSelectCoordsBuffer;
144
+    bool m_glyphsMustRecache;
140 145
 };
141 146
 
142 147
 #endif

Loading…
Cancel
Save