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
mFrameLatencyNeeded(false),
mFiltering(false),
mNeedsFiltering(false),
+ mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2),
mSecure(false),
mProtectedByApp(false),
mHasSurface(false),
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(
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
// 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();
}
// 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;
}
}
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
glVertexPointer(mesh.getVertexSize(),
GL_FLOAT,
mesh.getByteStride(),
- mesh.getVertices());
+ mesh.getPositions());
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
}
glVertexPointer(mesh.getVertexSize(),
GL_FLOAT,
mesh.getByteStride(),
- mesh.getVertices());
+ mesh.getPositions());
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
mesh.getVertexSize(),
GL_FLOAT, GL_FALSE,
mesh.getByteStride(),
- mesh.getVertices());
+ mesh.getPositions());
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
}
mesh.getVertexSize(),
GL_FLOAT, GL_FALSE,
mesh.getByteStride(),
- mesh.getVertices());
+ mesh.getPositions());
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
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;
}
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;
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);
}