Ver código fonte

Optimize text batch preparation by avoiding dynamic allocation each frame. Use last glyph if rendering the same glyph several times in a row. Changed repeated postincrement of a destination pointer to indexing where applicable.

Lasse Öörni 12 anos atrás
pai
commit
6219289e9f

+ 25 - 20
Source/Engine/Container/Str.cpp

@@ -874,38 +874,43 @@ void String::EncodeUTF8(char*& dest, unsigned unicodeChar)
         *dest++ = unicodeChar;
     else if (unicodeChar < 0x800)
     {
-        *dest++ = 0xc0 | ((unicodeChar >> 6) & 0x1f);
-        *dest++ = 0x80 | (unicodeChar & 0x3f);
+        dest[0] = 0xc0 | ((unicodeChar >> 6) & 0x1f);
+        dest[1] = 0x80 | (unicodeChar & 0x3f);
+        dest += 2;
     }
     else if (unicodeChar < 0x10000)
     {
-        *dest++ = 0xe0 | ((unicodeChar >> 12) & 0xf);
-        *dest++ = 0x80 | ((unicodeChar >> 6) & 0x3f);
-        *dest++ = 0x80 | (unicodeChar & 0x3f);
+        dest[0] = 0xe0 | ((unicodeChar >> 12) & 0xf);
+        dest[1] = 0x80 | ((unicodeChar >> 6) & 0x3f);
+        dest[2] = 0x80 | (unicodeChar & 0x3f);
+        dest += 3;
     }
     else if (unicodeChar < 0x200000)
     {
-        *dest++ = 0xf0 | ((unicodeChar >> 18) & 0x7);
-        *dest++ = 0x80 | ((unicodeChar >> 12) & 0x3f);
-        *dest++ = 0x80 | ((unicodeChar >> 6) & 0x3f);
-        *dest++ = 0x80 | (unicodeChar & 0x3f);
+        dest[0] = 0xf0 | ((unicodeChar >> 18) & 0x7);
+        dest[1] = 0x80 | ((unicodeChar >> 12) & 0x3f);
+        dest[2] = 0x80 | ((unicodeChar >> 6) & 0x3f);
+        dest[3] = 0x80 | (unicodeChar & 0x3f);
+        dest += 4;
     }
     else if (unicodeChar < 0x4000000)
     {
-        *dest++ = 0xf8 | ((unicodeChar >> 24) & 0x3);
-        *dest++ = 0x80 | ((unicodeChar >> 18) & 0x3f);
-        *dest++ = 0x80 | ((unicodeChar >> 12) & 0x3f);
-        *dest++ = 0x80 | ((unicodeChar >> 6) & 0x3f);
-        *dest++ = 0x80 | (unicodeChar & 0x3f);
+        dest[0] = 0xf8 | ((unicodeChar >> 24) & 0x3);
+        dest[1] = 0x80 | ((unicodeChar >> 18) & 0x3f);
+        dest[2] = 0x80 | ((unicodeChar >> 12) & 0x3f);
+        dest[3] = 0x80 | ((unicodeChar >> 6) & 0x3f);
+        dest[4] = 0x80 | (unicodeChar & 0x3f);
+        dest += 5;
     }
     else
     {
-        *dest++ = 0xfc | ((unicodeChar >> 30) & 0x1);
-        *dest++ = 0x80 | ((unicodeChar >> 24) & 0x3f);
-        *dest++ = 0x80 | ((unicodeChar >> 18) & 0x3f);
-        *dest++ = 0x80 | ((unicodeChar >> 12) & 0x3f);
-        *dest++ = 0x80 | ((unicodeChar >> 6) & 0x3f);
-        *dest++ = 0x80 | (unicodeChar & 0x3f);
+        dest[0] = 0xfc | ((unicodeChar >> 30) & 0x1);
+        dest[1] = 0x80 | ((unicodeChar >> 24) & 0x3f);
+        dest[2] = 0x80 | ((unicodeChar >> 18) & 0x3f);
+        dest[3] = 0x80 | ((unicodeChar >> 12) & 0x3f);
+        dest[4] = 0x80 | ((unicodeChar >> 6) & 0x3f);
+        dest[5] = 0x80 | (unicodeChar & 0x3f);
+        dest += 6;
     }
 }
 

+ 13 - 10
Source/Engine/Graphics/AnimatedModel.cpp

@@ -1028,24 +1028,27 @@ void AnimatedModel::CopyMorphVertices(void* destVertexData, void* srcVertexData,
         if (mask & MASK_POSITION)
         {
             float* posSrc = (float*)src;
-            *dest++ = posSrc[0];
-            *dest++ = posSrc[1];
-            *dest++ = posSrc[2];
+            dest[0] = posSrc[0];
+            dest[1] = posSrc[1];
+            dest[2] = posSrc[2];
+            dest += 3;
         }
         if (mask & MASK_NORMAL)
         {
             float* normalSrc = (float*)(src + normalOffset);
-            *dest++ = normalSrc[0];
-            *dest++ = normalSrc[1];
-            *dest++ = normalSrc[2];
+            dest[0] = normalSrc[0];
+            dest[1] = normalSrc[1];
+            dest[2] = normalSrc[2];
+            dest += 3;
         }
         if (mask & MASK_TANGENT)
         {
             float* tangentSrc = (float*)(src + tangentOffset);
-            *dest++ = tangentSrc[0];
-            *dest++ = tangentSrc[1];
-            *dest++ = tangentSrc[2];
-            *dest++ = tangentSrc[3];
+            dest[0] = tangentSrc[0];
+            dest[1] = tangentSrc[1];
+            dest[2] = tangentSrc[2];
+            dest[3] = tangentSrc[3];
+            dest += 4;
         }
 
         src += vertexSize;

+ 25 - 22
Source/Engine/Graphics/BillboardSet.cpp

@@ -371,9 +371,10 @@ void BillboardSet::UpdateBufferSize()
     unsigned vertexIndex = 0;
     while (numBillboards--)
     {
-        *dest++ = vertexIndex; *dest++ = vertexIndex + 1; *dest++ = vertexIndex + 2;
-        *dest++ = vertexIndex + 2; *dest++ = vertexIndex + 3; *dest++ = vertexIndex;
+        dest[0] = vertexIndex; dest[1] = vertexIndex + 1; dest[2] = vertexIndex + 2;
+        dest[3] = vertexIndex + 2; dest[4] = vertexIndex + 3; dest[5] = vertexIndex;
         
+        dest += 6;
         vertexIndex += 4;
     }
     
@@ -452,29 +453,31 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
         rotationMatrix[1][0] = -rotationMatrix[0][1];
         rotationMatrix[1][1] = rotationMatrix[0][0];
         
-        *dest++ = billboard.position_.x_; *dest++ = billboard.position_.y_; *dest++ = billboard.position_.z_;
-        *((unsigned*)dest) = color; dest++;
-        *dest++ = billboard.uv_.min_.x_; *dest++ = billboard.uv_.min_.y_;
-        *dest++ = -size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
-        *dest++ = -size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
+        dest[0] = billboard.position_.x_; dest[1] = billboard.position_.y_; dest[2] = billboard.position_.z_;
+        ((unsigned&)dest[3]) = color;
+        dest[4] = billboard.uv_.min_.x_; dest[5] = billboard.uv_.min_.y_;
+        dest[6] = -size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
+        dest[7] = -size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
         
-        *dest++ = billboard.position_.x_; *dest++ = billboard.position_.y_; *dest++ = billboard.position_.z_;
-        *((unsigned*)dest) = color; dest++;
-        *dest++ = billboard.uv_.max_.x_; *dest++ = billboard.uv_.min_.y_;
-        *dest++ = size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
-        *dest++ = size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
+        dest[8] = billboard.position_.x_; dest[9] = billboard.position_.y_; dest[10] = billboard.position_.z_;
+        ((unsigned&)dest[11]) = color;
+        dest[12] = billboard.uv_.max_.x_; dest[13] = billboard.uv_.min_.y_;
+        dest[14] = size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
+        dest[15] = size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
         
-        *dest++ = billboard.position_.x_; *dest++ = billboard.position_.y_; *dest++ = billboard.position_.z_;
-        *((unsigned*)dest) = color; dest++;
-        *dest++ = billboard.uv_.max_.x_; *dest++ = billboard.uv_.max_.y_;
-        *dest++ = size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
-        *dest++ = size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
+        dest[16] = billboard.position_.x_; dest[17] = billboard.position_.y_; dest[18] = billboard.position_.z_;
+        ((unsigned&)dest[19]) = color;
+        dest[20] = billboard.uv_.max_.x_; dest[21] = billboard.uv_.max_.y_;
+        dest[22] = size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
+        dest[23] = size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
         
-        *dest++ = billboard.position_.x_; *dest++ = billboard.position_.y_; *dest++ = billboard.position_.z_;
-        *((unsigned*)dest) = color; dest++;
-        *dest++ = billboard.uv_.min_.x_; *dest++ = billboard.uv_.max_.y_;
-        *dest++ = -size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
-        *dest++ = -size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
+        dest[24] = billboard.position_.x_; dest[25] = billboard.position_.y_; dest[26] = billboard.position_.z_;
+        ((unsigned&)dest[27]) = color;
+        dest[28] = billboard.uv_.min_.x_; dest[29] = billboard.uv_.max_.y_;
+        dest[30] = -size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
+        dest[31] = -size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
+
+        dest += 32;
     }
     
     vertexBuffer_->Unlock();

+ 10 - 8
Source/Engine/Graphics/DebugRenderer.cpp

@@ -336,22 +336,24 @@ void DebugRenderer::Render()
     {
         const DebugLine& line = lines_[i];
 
-        *dest++ = line.start_.x_; *dest++ = line.start_.y_; *dest++ = line.start_.z_;
-        *((unsigned*)dest) = line.color_; dest++;
+        dest[0] = line.start_.x_; dest[1] = line.start_.y_; dest[2] = line.start_.z_;
+        ((unsigned&)dest[3]) = line.color_;
+        dest[4] = line.end_.x_; dest[5] = line.end_.y_; dest[6] = line.end_.z_;
+        ((unsigned&)dest[7]) = line.color_;
 
-        *dest++ = line.end_.x_; *dest++ = line.end_.y_; *dest++ = line.end_.z_;
-        *((unsigned*)dest) = line.color_; dest++;
+        dest += 8;
     }
 
     for (unsigned i = 0; i < noDepthLines_.Size(); ++i)
     {
         const DebugLine& line = noDepthLines_[i];
 
-        *dest++ = line.start_.x_; *dest++ = line.start_.y_; *dest++ = line.start_.z_;
-        *((unsigned*)dest) = line.color_; dest++;
+        dest[0] = line.start_.x_; dest[1] = line.start_.y_; dest[2] = line.start_.z_;
+        ((unsigned&)dest[3]) = line.color_;
+        dest[4] = line.end_.x_; dest[5] = line.end_.y_; dest[6] = line.end_.z_;
+        ((unsigned&)dest[7]) = line.color_;
 
-        *dest++ = line.end_.x_; *dest++ = line.end_.y_; *dest++ = line.end_.z_;
-        *((unsigned*)dest) = line.color_; dest++;
+        dest += 8;
     }
 
     vertexBuffer_->Unlock();

+ 8 - 6
Source/Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -555,9 +555,10 @@ bool Graphics::TakeScreenShot(Image& destImage)
                 int g = (rgb >> 5) & 63;
                 int r = (rgb >> 11);
                 
-                *dest++ = (int)(r * 255.0f / 31.0f);
-                *dest++ = (int)(g * 255.0f / 63.0f);
-                *dest++ = (int)(b * 255.0f / 31.0f);
+                dest[0] = (int)(r * 255.0f / 31.0f);
+                dest[1] = (int)(g * 255.0f / 63.0f);
+                dest[2] = (int)(b * 255.0f / 31.0f);
+                dest += 3;
             }
         }
     }
@@ -570,10 +571,11 @@ bool Graphics::TakeScreenShot(Image& destImage)
             
             for (int x = 0; x < width_; ++x)
             {
-                *dest++ = src[2];
-                *dest++ = src[1];
-                *dest++ = src[0];
+                dest[0] = src[2];
+                dest[1] = src[1];
+                dest[2] = src[0];
                 src += 4;
+                dest += 3;
             }
         }
     }

+ 9 - 8
Source/Engine/Graphics/Renderer.cpp

@@ -1713,16 +1713,17 @@ void Renderer::SetIndirectionTextureData()
             for (unsigned x = 0; x < 256; ++x)
             {
                 #ifdef USE_OPENGL
-                *dest++ = x;
-                *dest++ = 255 - y;
-                *dest++ = faceX;
-                *dest++ = 255 * 2 / 3 - faceY;
+                dest[0] = x;
+                dest[1] = 255 - y;
+                dest[2] = faceX;
+                dest[3] = 255 * 2 / 3 - faceY;
                 #else
-                *dest++ = x;
-                *dest++ = y;
-                *dest++ = faceX;
-                *dest++ = faceY;
+                dest[0] = x;
+                dest[1] = y;
+                dest[2] = faceX;
+                dest[3] = faceY;
                 #endif
+                dest += 4;
             }
         }
         

+ 13 - 5
Source/Engine/UI/Text.cpp

@@ -166,11 +166,13 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
         if (textures.Size() > 1)
         {
             // Only traversing thru the printText once regardless of number of textures/pages in the font
-            Vector<PODVector<GlyphLocation> > pageGlyphLocations(textures.Size());
-
+            pageGlyphLocations_.Resize(textures.Size());
+            
             unsigned rowIndex = 0;
             int x = GetRowStartPosition(rowIndex);
             int y = 0;
+            const FontGlyph* p = 0;
+            unsigned last = 0;
 
             for (unsigned i = 0; i < printText_.Size(); ++i)
             {
@@ -178,13 +180,19 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
 
                 if (c != '\n')
                 {
-                    const FontGlyph* p = face->GetGlyph(c);
+                    // Optimize if same glyph requested several times in a row
+                    if (!p || c != last)
+                    {
+                        p = face->GetGlyph(c);
+                        last = c;
+                    }
+
                     if (!p)
                         continue;
 
                     // Validate page because of possible glyph unallocations (should not happen, though)
                     if (p->page_ < textures.Size())
-                        pageGlyphLocations[p->page_].Push(GlyphLocation(x, y, p));
+                        pageGlyphLocations_[p->page_].Push(GlyphLocation(x, y, p));
 
                     x += p->advanceX_;
                     if (i < printText_.Size() - 1)
@@ -202,7 +210,7 @@ void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData,
                 // One batch per texture/page
                 UIBatch pageBatch(this, BLEND_ALPHA, currentScissor, textures[n], &vertexData);
 
-                const PODVector<GlyphLocation>& pageGlyphLocation = pageGlyphLocations[n];
+                const PODVector<GlyphLocation>& pageGlyphLocation = pageGlyphLocations_[n];
 
                 switch (textEffect_)
                 {

+ 12 - 6
Source/Engine/UI/Text.h

@@ -41,19 +41,23 @@ enum TextEffect
     TE_STROKE
 };
 
-/// Glyph location.
+/// Glyph and its location within the text. Used when preparing text rendering.
 struct GlyphLocation
 {
-    int x_;
-    int y_;
-    const FontGlyph* glyph_;
-
+    // Construct.
     GlyphLocation(int x, int y, const FontGlyph* glyph) :
-    x_(x),
+        x_(x),
         y_(y),
         glyph_(glyph)
     {
     }
+
+    /// X coordinate.
+    int x_;
+    /// Y coordinate.
+    int y_;
+    /// Glyph.
+    const FontGlyph* glyph_;
 };
 
 /// %Text %UI element.
@@ -199,6 +203,8 @@ protected:
     PODVector<IntVector2> charPositions_;
     /// Sizes of each character.
     PODVector<IntVector2> charSizes_;
+    /// Glyph locations per each texture in the font.
+    Vector<PODVector<GlyphLocation> > pageGlyphLocations_;
 };
 
 }

+ 38 - 36
Source/Engine/UI/UIBatch.cpp

@@ -128,29 +128,31 @@ void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int t
     float* dest = &(vertexData_->At(begin));
     vertexEnd_ = vertexData_->Size();
     
-    *dest++ = left; *dest++ = top; *dest++ = 0.0f;
-    *((unsigned*)dest) = topLeftColor; dest++;
-    *dest++ = leftUV; *dest++ = topUV;
+    dest[0] = left; dest[1] = top; dest[2] = 0.0f;
+    ((unsigned&)dest[3]) = topLeftColor;
+    dest[4] = leftUV; dest[5] = topUV;
     
-    *dest++ = right; *dest++ = top; *dest++ = 0.0f;
-    *((unsigned*)dest) = topRightColor; dest++;
-    *dest++ = rightUV; *dest++ = topUV;
+    dest[6] = right; dest[7] = top; dest[8] = 0.0f;
+    ((unsigned&)dest[9]) = topRightColor;
+    dest[10] = rightUV; dest[11] = topUV;
     
-    *dest++ = left; *dest++ = bottom; *dest++ = 0.0f;
-    *((unsigned*)dest) = bottomLeftColor; dest++;
-    *dest++ = leftUV; *dest++ = bottomUV;
+    dest[12] = left; dest[13] = bottom; dest[14] = 0.0f;
+    ((unsigned&)dest[15]) = bottomLeftColor;
+    dest[16] = leftUV; dest[17] = bottomUV;
     
-    *dest++ = right; *dest++ = top; *dest++ = 0.0f;
-    *((unsigned*)dest) = topRightColor; dest++;
-    *dest++ = rightUV; *dest++ = topUV;
+    dest[18] = right; dest[19] = top; dest[20] = 0.0f;
+    ((unsigned&)dest[21]) = topRightColor;
+    dest[22] = rightUV; dest[23] = topUV;
     
-    *dest++ = right; *dest++ = bottom; *dest++ = 0.0f;
-    *((unsigned*)dest) = bottomRightColor; dest++;
-    *dest++ = rightUV; *dest++ = bottomUV;
+    dest[24] = right; dest[25] = bottom; dest[26] = 0.0f;
+    ((unsigned&)dest[27]) = bottomRightColor;
+    dest[28] = rightUV; dest[29] = bottomUV;
 
-    *dest++ = left; *dest++ = bottom; *dest++ = 0.0f;
-    *((unsigned*)dest) = bottomLeftColor; dest++;
-    *dest++ = leftUV; *dest++ = bottomUV;
+    dest[30] = left; dest[31] = bottom; dest[32] = 0.0f;
+    ((unsigned&)dest[33]) = bottomLeftColor;
+    dest[34] = leftUV; dest[35] = bottomUV;
+
+    dest += 36;
 }
 
 void UIBatch::AddQuad(const Matrix3x4& transform, int x, int y, int width, int height, int texOffsetX, int texOffsetY,
@@ -192,29 +194,29 @@ void UIBatch::AddQuad(const Matrix3x4& transform, int x, int y, int width, int h
     float* dest = &(vertexData_->At(begin));
     vertexEnd_ = vertexData_->Size();
 
-    *dest++ = v1.x_; *dest++ = v1.y_; *dest++ = 0.0f;
-    *((unsigned*)dest) = topLeftColor; dest++;
-    *dest++ = leftUV; *dest++ = topUV;
+    dest[0] = v1.x_; dest[1] = v1.y_; dest[2] = 0.0f;
+    ((unsigned&)dest[3]) = topLeftColor;
+    dest[4] = leftUV; dest[5] = topUV;
     
-    *dest++ = v2.x_; *dest++ = v2.y_; *dest++ = 0.0f;
-    *((unsigned*)dest) = topRightColor; dest++;
-    *dest++ = rightUV; *dest++ = topUV;
+    dest[6] = v2.x_; dest[7] = v2.y_; dest[8] = 0.0f;
+    ((unsigned&)dest[9]) = topRightColor;
+    dest[10] = rightUV; dest[11] = topUV;
     
-    *dest++ = v3.x_; *dest++ = v3.y_; *dest++ = 0.0f;
-    *((unsigned*)dest) = bottomLeftColor; dest++;
-    *dest++ = leftUV; *dest++ = bottomUV;
+    dest[12] = v3.x_; dest[13] = v3.y_; dest[14] = 0.0f;
+    ((unsigned&)dest[15]) = bottomLeftColor;
+    dest[16] = leftUV; dest[17] = bottomUV;
     
-    *dest++ = v2.x_; *dest++ = v2.y_; *dest++ = 0.0f;
-    *((unsigned*)dest) = topRightColor; dest++;
-    *dest++ = rightUV; *dest++ = topUV;
+    dest[18] = v2.x_; dest[19] = v2.y_; dest[20] = 0.0f;
+    ((unsigned&)dest[21]) = topRightColor;
+    dest[22] = rightUV; dest[23] = topUV;
     
-    *dest++ = v4.x_; *dest++ = v4.y_; *dest++ = 0.0f;
-    *((unsigned*)dest) = bottomRightColor; dest++;
-    *dest++ = rightUV; *dest++ = bottomUV;
+    dest[24] = v4.x_; dest[25] = v4.y_; dest[26] = 0.0f;
+    ((unsigned&)dest[27]) = bottomRightColor;
+    dest[28] = rightUV; dest[29] = bottomUV;
 
-    *dest++ = v3.x_; *dest++ = v3.y_; *dest++ = 0.0f;
-    *((unsigned*)dest) = bottomLeftColor; dest++;
-    *dest++ = leftUV; *dest++ = bottomUV;
+    dest[30] = v3.x_; dest[31] = v3.y_; dest[32] = 0.0f;
+    ((unsigned&)dest[33]) = bottomLeftColor;
+    dest[34] = leftUV; dest[35] = bottomUV;
 }
 
 void UIBatch::AddQuad(int x, int y, int width, int height, int texOffsetX, int texOffsetY, int texWidth, int texHeight, bool tiled)