OSDN Git Service

don't reallocate the mesh each time we use it
authorMathias Agopian <mathias@google.com>
Wed, 14 Aug 2013 03:51:23 +0000 (20:51 -0700)
committerMathias Agopian <mathias@google.com>
Wed, 14 Aug 2013 03:51:23 +0000 (20:51 -0700)
the Mesh object can be part of each Layer (at least currently).
also reworked the Mesh code a bit to make it easier to access
the vertex data.

Change-Id: I0490851ba898f0aa2e55b62958dcd8bdb535e98b

services/surfaceflinger/Layer.cpp
services/surfaceflinger/Layer.h
services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
services/surfaceflinger/RenderEngine/Mesh.cpp
services/surfaceflinger/RenderEngine/Mesh.h
services/surfaceflinger/RenderEngine/RenderEngine.cpp

index cf4ec57..a63a80a 100644 (file)
@@ -74,6 +74,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
         mFrameLatencyNeeded(false),
         mFiltering(false),
         mNeedsFiltering(false),
+        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
         mSecure(false),
         mProtectedByApp(false),
         mHasSurface(false),
@@ -494,9 +495,8 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
 void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
         float red, float green, float blue, float alpha) const
 {
-    Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
-    computeGeometry(hw, mesh);
-    mFlinger->getRenderEngine().fillWithColor(mesh, red, green, blue, alpha);
+    computeGeometry(hw, mMesh);
+    mFlinger->getRenderEngine().fillWithColor(mMesh, red, green, blue, alpha);
 }
 
 void Layer::clearWithOpenGL(
@@ -509,8 +509,7 @@ void Layer::drawWithOpenGL(
     const uint32_t fbHeight = hw->getHeight();
     const State& s(getDrawingState());
 
-    Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
-    computeGeometry(hw, mesh);
+    computeGeometry(hw, mMesh);
 
     /*
      * NOTE: the way we compute the texture coordinates here produces
@@ -535,20 +534,19 @@ void Layer::drawWithOpenGL(
 
     // TODO: we probably want to generate the texture coords with the mesh
     // here we assume that we only have 4 vertices
-    size_t stride = mesh.getStride();
-    float* base = mesh.getTexCoords();
-    base[stride*0 + 0] = left;
-    base[stride*0 + 1] = 1.0f - top;
-    base[stride*1 + 0] = left;
-    base[stride*1 + 1] = 1.0f - bottom;
-    base[stride*2 + 0] = right;
-    base[stride*2 + 1] = 1.0f - bottom;
-    base[stride*3 + 0] = right;
-    base[stride*3 + 1] = 1.0f - top;
+    Mesh::VertexArray texCoords(mMesh.getTexCoordArray());
+    texCoords[0].s = left;
+    texCoords[0].t = 1.0f - top;
+    texCoords[1].s = left;
+    texCoords[1].t = 1.0f - bottom;
+    texCoords[2].s = right;
+    texCoords[2].t = 1.0f - bottom;
+    texCoords[3].s = right;
+    texCoords[3].t = 1.0f - top;
 
     RenderEngine& engine(mFlinger->getRenderEngine());
     engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
-    engine.drawMesh(mesh);
+    engine.drawMesh(mMesh);
     engine.disableBlending();
 }
 
@@ -596,12 +594,13 @@ void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
     // subtract the transparent region and snap to the bounds
     win = reduce(win, s.activeTransparentRegion);
 
-    tr.transform(mesh[0], win.left,  win.top);
-    tr.transform(mesh[1], win.left,  win.bottom);
-    tr.transform(mesh[2], win.right, win.bottom);
-    tr.transform(mesh[3], win.right, win.top);
+    Mesh::VertexArray position(mesh.getPositionArray());
+    tr.transform(position[0], win.left,  win.top);
+    tr.transform(position[1], win.left,  win.bottom);
+    tr.transform(position[2], win.right, win.bottom);
+    tr.transform(position[3], win.right, win.top);
     for (size_t i=0 ; i<4 ; i++) {
-        mesh[i][1] = hw_h - mesh[i][1];
+        position[i].y = hw_h - position[i].y;
     }
 }
 
index 27e0c69..faf3666 100644 (file)
@@ -357,6 +357,8 @@ private:
     bool mFiltering;
     // Whether filtering is needed b/c of the drawingstate
     bool mNeedsFiltering;
+    // The mesh used to draw the layer in GLES composition mode
+    mutable Mesh mMesh;
 
     // page-flip thread (currently main thread)
     bool mSecure; // no screenshots
index 27105a2..428cdb8 100644 (file)
@@ -192,7 +192,7 @@ void GLES11RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float
     glVertexPointer(mesh.getVertexSize(),
             GL_FLOAT,
             mesh.getByteStride(),
-            mesh.getVertices());
+            mesh.getPositions());
 
     glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
 }
@@ -209,7 +209,7 @@ void GLES11RenderEngine::drawMesh(const Mesh& mesh) {
     glVertexPointer(mesh.getVertexSize(),
             GL_FLOAT,
             mesh.getByteStride(),
-            mesh.getVertices());
+            mesh.getPositions());
 
     glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
 
index 6786065..9be12bf 100644 (file)
@@ -168,7 +168,7 @@ void GLES20RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float
             mesh.getVertexSize(),
             GL_FLOAT, GL_FALSE,
             mesh.getByteStride(),
-            mesh.getVertices());
+            mesh.getPositions());
 
     glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
 }
@@ -190,7 +190,7 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) {
             mesh.getVertexSize(),
             GL_FLOAT, GL_FALSE,
             mesh.getByteStride(),
-            mesh.getVertices());
+            mesh.getPositions());
 
     glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
 
index a08eea6..3f50cb0 100644 (file)
@@ -30,23 +30,15 @@ Mesh::~Mesh() {
     delete [] mVertices;
 }
 
-float const* Mesh::operator[](size_t index) const {
-    return &mVertices[index * mStride];
-}
-
-float* Mesh::operator[](size_t index) {
-    return &mVertices[index * mStride];
-}
-
 Mesh::Primitive Mesh::getPrimitive() const {
     return mPrimitive;
 }
 
 
-float const* Mesh::getVertices() const {
+float const* Mesh::getPositions() const {
     return mVertices;
 }
-float* Mesh::getVertices() {
+float* Mesh::getPositions() {
     return mVertices;
 }
 
index 599a150..160d765 100644 (file)
@@ -24,34 +24,72 @@ namespace android {
 class Mesh {
 public:
     enum Primitive {
-        TRIANGLES       = 0x0004,
-        TRIANGLE_STRIP  = 0x0005,
-        TRIANGLE_FAN    = 0x0006
+        TRIANGLES       = 0x0004,       // GL_TRIANGLES
+        TRIANGLE_STRIP  = 0x0005,       // GL_TRIANGLE_STRIP
+        TRIANGLE_FAN    = 0x0006        // GL_TRIANGLE_FAN
     };
 
     Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordsSize = 0);
     ~Mesh();
 
-    float const* operator[](size_t index) const;
-    float* operator[](size_t index);
+    /*
+     * VertexArray handles the stride automatically. It also provides
+     * a convenient way to set position and texture coordinates by using
+     * the usual x,y,z,w or s,t,r,q names.
+     */
+    class VertexArray {
+        friend class Mesh;
+        float* mData;
+        size_t mStride;
+        VertexArray(float* data, size_t stride) : mData(data), mStride(stride) { }
+    public:
+        struct vertexData {
+            operator float*() { return reinterpret_cast<float*>(this); }
+            union {
+                struct { float x, y, z, w; };
+                struct { float s, t, r, q; };
+            };
+        };
+        vertexData& operator[](size_t index) {
+            return *reinterpret_cast<vertexData*>(&mData[index*mStride]); }
 
+        vertexData const& operator[](size_t index) const {
+            return *reinterpret_cast<vertexData const*>(&mData[index*mStride]); }
+    };
+
+    VertexArray getPositionArray() { return VertexArray(getPositions(), mStride); }
+    VertexArray getTexCoordArray() { return VertexArray(getTexCoords(), mStride); }
 
     Primitive getPrimitive() const;
 
-    float const* getVertices() const;
-    float* getVertices();
+    // returns a pointer to the vertices positions
+    float const* getPositions() const;
 
+    // returns a pointer to the vertices  texture coordinates
     float const* getTexCoords() const;
-    float* getTexCoords();
 
+    // number of vertices in this mesh
     size_t getVertexCount() const;
+
+    // dimension of vertices
     size_t getVertexSize() const;
+
+    // dimension of texture coordinates
     size_t getTexCoordsSize() const;
 
+    // return stride in bytes
     size_t getByteStride() const;
+
+    // return stride in floats
     size_t getStride() const;
 
 private:
+    Mesh(const Mesh&);
+    Mesh& operator = (const Mesh&);
+    Mesh const& operator = (const Mesh&) const;
+
+    float* getPositions();
+    float* getTexCoords();
     float* mVertices;
     size_t mVertexCount;
     size_t mVertexSize;
index e8016ee..ee51bd9 100644 (file)
@@ -149,19 +149,20 @@ void RenderEngine::fillRegionWithColor(const Region& region, uint32_t height,
     size_t c;
     Rect const* r = region.getArray(&c);
     Mesh mesh(Mesh::TRIANGLES, c*6, 2);
+    Mesh::VertexArray position(mesh.getPositionArray());
     for (size_t i=0 ; i<c ; i++, r++) {
-        mesh[i*6 + 0][0] = r->left;
-        mesh[i*6 + 0][1] = height - r->top;
-        mesh[i*6 + 1][0] = r->left;
-        mesh[i*6 + 1][1] = height - r->bottom;
-        mesh[i*6 + 2][0] = r->right;
-        mesh[i*6 + 2][1] = height - r->bottom;
-        mesh[i*6 + 3][0] = r->left;
-        mesh[i*6 + 3][1] = height - r->top;
-        mesh[i*6 + 4][0] = r->right;
-        mesh[i*6 + 4][1] = height - r->bottom;
-        mesh[i*6 + 5][0] = r->right;
-        mesh[i*6 + 5][1] = height - r->top;
+        position[i*6 + 0].x = r->left;
+        position[i*6 + 0].y = height - r->top;
+        position[i*6 + 1].x = r->left;
+        position[i*6 + 1].y = height - r->bottom;
+        position[i*6 + 2].x = r->right;
+        position[i*6 + 2].y = height - r->bottom;
+        position[i*6 + 3].x = r->left;
+        position[i*6 + 3].y = height - r->top;
+        position[i*6 + 4].x = r->right;
+        position[i*6 + 4].y = height - r->bottom;
+        position[i*6 + 5].x = r->right;
+        position[i*6 + 5].y = height - r->top;
     }
     fillWithColor(mesh, red, green, blue, alpha);
 }