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
This commit is contained in:
Mathias Agopian 2013-08-13 20:51:23 -07:00
parent 3f84483382
commit 5cdc8994a0
7 changed files with 87 additions and 55 deletions

View 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;
}
}

View 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

View 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());

View 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());

View 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;
}

View 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;

View 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);
}