diff options
author | 2013-08-13 20:51:23 -0700 | |
---|---|---|
committer | 2013-08-13 20:51:23 -0700 | |
commit | 5cdc8994a0ecd751a6350b16a1bef8b6b0d09b11 (patch) | |
tree | dd59d9f3e94274d6d8cf46fb28780a78392a3e4f | |
parent | 3f84483382be2d528918cc1a6fbc6a7d68e0b181 (diff) |
don't reallocate the mesh each time we use it
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
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 41 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 2 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp | 4 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/Mesh.cpp | 12 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/Mesh.h | 54 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/RenderEngine.cpp | 25 |
7 files changed, 87 insertions, 55 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index cf4ec57ebd..a63a80a29b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -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; } } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 27e0c696f1..faf3666543 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -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 diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp index 27105a2f4e..428cdb846f 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp @@ -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()); diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 6786065e4b..9be12bf1e1 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -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()); diff --git a/services/surfaceflinger/RenderEngine/Mesh.cpp b/services/surfaceflinger/RenderEngine/Mesh.cpp index a08eea611d..3f50cb0a96 100644 --- a/services/surfaceflinger/RenderEngine/Mesh.cpp +++ b/services/surfaceflinger/RenderEngine/Mesh.cpp @@ -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; } diff --git a/services/surfaceflinger/RenderEngine/Mesh.h b/services/surfaceflinger/RenderEngine/Mesh.h index 599a15066c..160d765ba2 100644 --- a/services/surfaceflinger/RenderEngine/Mesh.h +++ b/services/surfaceflinger/RenderEngine/Mesh.h @@ -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; diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp index e8016ee34f..ee51bd9d1a 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp @@ -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); } |