summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2019-12-09 19:53:19 -0800
committer Vishnu Nair <vishnun@google.com> 2019-12-10 09:04:08 -0800
commit440992f66c76322228c6817190839bb56e9a8845 (patch)
treedd20deb8e032ea1e9c3b47013803bd5fb0fce05f
parent0d4bd95f746fe21e2a24b1e66d2215acc130e136 (diff)
[Shadows] Add support for shadow attributes (7/n)
There are two types of shadows that need to be drawn, spot and ambient shadows. Each shadow can support different colors. The GL code generates three vertex attributes for each shadow, its position, color and shadow params(offset and distance). These can be sent using a single glDrawElements call. In order to support this, this change: - adds a builder to Mesh class to support mixing and matching gl attributes - adds support to offset VertexArrays so we can attributes for multiple shadows to one array - modifies drawLayers to support drawing shadows (actual draw shadow code will be in a follow up cl) - adds draw shadow state to render engine Bug: 136561771 Test: go/wm-smoke Test: atest librenderengine_test libgui_test SurfaceFlinger_test Change-Id: I2e70c3dbba3266e44896d5b25e45640defe6353b
-rw-r--r--libs/gui/LayerState.cpp3
-rw-r--r--libs/renderengine/Mesh.cpp56
-rw-r--r--libs/renderengine/gl/GLESRenderEngine.cpp62
-rw-r--r--libs/renderengine/gl/Program.cpp2
-rw-r--r--libs/renderengine/gl/Program.h8
-rw-r--r--libs/renderengine/include/renderengine/Mesh.h96
-rw-r--r--libs/renderengine/include/renderengine/private/Description.h3
7 files changed, 199 insertions, 31 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index e392bc597f..e033f93286 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -109,7 +109,7 @@ status_t layer_state_t::write(Parcel& output) const
return err;
}
}
-
+ output.writeFloat(shadowRadius);
return NO_ERROR;
}
@@ -187,6 +187,7 @@ status_t layer_state_t::read(const Parcel& input)
input.readInt64Vector(&callbackIds);
listeners.emplace_back(listener, callbackIds);
}
+ shadowRadius = input.readFloat();
return NO_ERROR;
}
diff --git a/libs/renderengine/Mesh.cpp b/libs/renderengine/Mesh.cpp
index f5387f28ea..ed2f45fdf5 100644
--- a/libs/renderengine/Mesh.cpp
+++ b/libs/renderengine/Mesh.cpp
@@ -21,38 +21,46 @@
namespace android {
namespace renderengine {
-Mesh::Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize)
+Mesh::Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize,
+ size_t cropCoordsSize, size_t shadowColorSize, size_t shadowParamsSize,
+ size_t indexCount)
: mVertexCount(vertexCount),
mVertexSize(vertexSize),
mTexCoordsSize(texCoordSize),
- mPrimitive(primitive) {
+ mCropCoordsSize(cropCoordsSize),
+ mShadowColorSize(shadowColorSize),
+ mShadowParamsSize(shadowParamsSize),
+ mPrimitive(primitive),
+ mIndexCount(indexCount) {
if (vertexCount == 0) {
mVertices.resize(1);
mVertices[0] = 0.0f;
mStride = 0;
return;
}
-
- const size_t CROP_COORD_SIZE = 2;
- size_t stride = vertexSize + texCoordSize + CROP_COORD_SIZE;
+ size_t stride = vertexSize + texCoordSize + cropCoordsSize + shadowColorSize + shadowParamsSize;
size_t remainder = (stride * vertexCount) / vertexCount;
// Since all of the input parameters are unsigned, if stride is less than
// either vertexSize or texCoordSize, it must have overflowed. remainder
// will be equal to stride as long as stride * vertexCount doesn't overflow.
if ((stride < vertexSize) || (remainder != stride)) {
- ALOGE("Overflow in Mesh(..., %zu, %zu, %zu, %zu)", vertexCount, vertexSize, texCoordSize,
- CROP_COORD_SIZE);
+ ALOGE("Overflow in Mesh(..., %zu, %zu, %zu, %zu, %zu, %zu)", vertexCount, vertexSize,
+ texCoordSize, cropCoordsSize, shadowColorSize, shadowParamsSize);
mVertices.resize(1);
mVertices[0] = 0.0f;
mVertexCount = 0;
mVertexSize = 0;
mTexCoordsSize = 0;
+ mCropCoordsSize = 0;
+ mShadowColorSize = 0;
+ mShadowParamsSize = 0;
mStride = 0;
return;
}
mVertices.resize(stride * vertexCount);
mStride = stride;
+ mIndices.resize(indexCount);
}
Mesh::Primitive Mesh::getPrimitive() const {
@@ -80,6 +88,28 @@ float* Mesh::getCropCoords() {
return mVertices.data() + mVertexSize + mTexCoordsSize;
}
+float const* Mesh::getShadowColor() const {
+ return mVertices.data() + mVertexSize + mTexCoordsSize + mCropCoordsSize;
+}
+float* Mesh::getShadowColor() {
+ return mVertices.data() + mVertexSize + mTexCoordsSize + mCropCoordsSize;
+}
+
+float const* Mesh::getShadowParams() const {
+ return mVertices.data() + mVertexSize + mTexCoordsSize + mCropCoordsSize + mShadowColorSize;
+}
+float* Mesh::getShadowParams() {
+ return mVertices.data() + mVertexSize + mTexCoordsSize + mCropCoordsSize + mShadowColorSize;
+}
+
+uint16_t const* Mesh::getIndices() const {
+ return mIndices.data();
+}
+
+uint16_t* Mesh::getIndices() {
+ return mIndices.data();
+}
+
size_t Mesh::getVertexCount() const {
return mVertexCount;
}
@@ -92,6 +122,14 @@ size_t Mesh::getTexCoordsSize() const {
return mTexCoordsSize;
}
+size_t Mesh::getShadowColorSize() const {
+ return mShadowColorSize;
+}
+
+size_t Mesh::getShadowParamsSize() const {
+ return mShadowParamsSize;
+}
+
size_t Mesh::getByteStride() const {
return mStride * sizeof(float);
}
@@ -100,5 +138,9 @@ size_t Mesh::getStride() const {
return mStride;
}
+size_t Mesh::getIndexCount() const {
+ return mIndexCount;
+}
+
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 394d05a876..d1378d566c 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -566,7 +566,10 @@ void GLESRenderEngine::fillRegionWithColor(const Region& region, float red, floa
float alpha) {
size_t c;
Rect const* r = region.getArray(&c);
- Mesh mesh(Mesh::TRIANGLES, c * 6, 2);
+ Mesh mesh = Mesh::Builder()
+ .setPrimitive(Mesh::TRIANGLES)
+ .setVertices(c * 6 /* count */, 2 /* size */)
+ .build();
Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>());
for (size_t i = 0; i < c; i++, r++) {
position[i * 6 + 0].x = r->left;
@@ -981,7 +984,12 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
fillRegionWithColor(display.clearRegion, 0.0, 0.0, 0.0, 1.0);
}
- Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
+ Mesh mesh = Mesh::Builder()
+ .setPrimitive(Mesh::TRIANGLE_FAN)
+ .setVertices(4 /* count */, 2 /* size */)
+ .setTexCoords(2 /* size */)
+ .setCropCoords(2 /* size */)
+ .build();
for (auto layer : layers) {
mState.maxMasteringLuminance = layer.source.buffer.maxMasteringLuminance;
mState.maxContentLuminance = layer.source.buffer.maxContentLuminance;
@@ -1037,10 +1045,13 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
}
setSourceDataSpace(layer.sourceDataspace);
+ if (layer.shadow.length > 0.0f) {
+ // handle shadows
+ }
// We only want to do a special handling for rounded corners when having rounded corners
// is the only reason it needs to turn on blending, otherwise, we handle it like the
// usual way since it needs to turn on blending anyway.
- if (layer.geometry.roundedCornersRadius > 0.0 && color.a >= 1.0f && isOpaque) {
+ else if (layer.geometry.roundedCornersRadius > 0.0 && color.a >= 1.0f && isOpaque) {
handleRoundedCorners(display, layer, mesh);
} else {
drawMesh(mesh);
@@ -1178,13 +1189,23 @@ void GLESRenderEngine::drawMesh(const Mesh& mesh) {
mesh.getByteStride(), mesh.getCropCoords());
}
+ if (mState.drawShadows) {
+ glEnableVertexAttribArray(Program::shadowColor);
+ glVertexAttribPointer(Program::shadowColor, mesh.getShadowColorSize(), GL_FLOAT, GL_FALSE,
+ mesh.getByteStride(), mesh.getShadowColor());
+
+ glEnableVertexAttribArray(Program::shadowParams);
+ glVertexAttribPointer(Program::shadowParams, mesh.getShadowParamsSize(), GL_FLOAT, GL_FALSE,
+ mesh.getByteStride(), mesh.getShadowParams());
+ }
+
+ Description managedState = mState;
// By default, DISPLAY_P3 is the only supported wide color output. However,
// when HDR content is present, hardware composer may be able to handle
// BT2020 data space, in that case, the output data space is set to be
// BT2020_HLG or BT2020_PQ respectively. In GPU fall back we need
// to respect this and convert non-HDR content to HDR format.
if (mUseColorManagement) {
- Description managedState = mState;
Dataspace inputStandard = static_cast<Dataspace>(mDataSpace & Dataspace::STANDARD_MASK);
Dataspace inputTransfer = static_cast<Dataspace>(mDataSpace & Dataspace::TRANSFER_MASK);
Dataspace outputStandard =
@@ -1275,27 +1296,25 @@ void GLESRenderEngine::drawMesh(const Mesh& mesh) {
managedState.outputTransferFunction =
Description::dataSpaceToTransferFunction(outputTransfer);
}
+ }
- ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext
- : mEGLContext,
- managedState);
-
- glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
+ ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext : mEGLContext,
+ managedState);
- if (outputDebugPPMs) {
- static uint64_t managedColorFrameCount = 0;
- std::ostringstream out;
- out << "/data/texture_out" << managedColorFrameCount++;
- writePPM(out.str().c_str(), mVpWidth, mVpHeight);
- }
+ if (mState.drawShadows) {
+ glDrawElements(mesh.getPrimitive(), mesh.getIndexCount(), GL_UNSIGNED_SHORT,
+ mesh.getIndices());
} else {
- ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext
- : mEGLContext,
- mState);
-
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
}
+ if (mUseColorManagement && outputDebugPPMs) {
+ static uint64_t managedColorFrameCount = 0;
+ std::ostringstream out;
+ out << "/data/texture_out" << managedColorFrameCount++;
+ writePPM(out.str().c_str(), mVpWidth, mVpHeight);
+ }
+
if (mesh.getTexCoordsSize()) {
glDisableVertexAttribArray(Program::texCoords);
}
@@ -1303,6 +1322,11 @@ void GLESRenderEngine::drawMesh(const Mesh& mesh) {
if (mState.cornerRadius > 0.0f) {
glDisableVertexAttribArray(Program::cropCoords);
}
+
+ if (mState.drawShadows) {
+ glDisableVertexAttribArray(Program::shadowColor);
+ glDisableVertexAttribArray(Program::shadowParams);
+ }
}
size_t GLESRenderEngine::getMaxTextureSize() const {
diff --git a/libs/renderengine/gl/Program.cpp b/libs/renderengine/gl/Program.cpp
index 4eb5eb6a25..f4fbf3524a 100644
--- a/libs/renderengine/gl/Program.cpp
+++ b/libs/renderengine/gl/Program.cpp
@@ -37,6 +37,8 @@ Program::Program(const ProgramCache::Key& /*needs*/, const char* vertex, const c
glBindAttribLocation(programId, position, "position");
glBindAttribLocation(programId, texCoords, "texCoords");
glBindAttribLocation(programId, cropCoords, "cropCoords");
+ glBindAttribLocation(programId, shadowColor, "shadowColor");
+ glBindAttribLocation(programId, shadowParams, "shadowParams");
glLinkProgram(programId);
GLint status;
diff --git a/libs/renderengine/gl/Program.h b/libs/renderengine/gl/Program.h
index c9beb6844f..fc3755e78f 100644
--- a/libs/renderengine/gl/Program.h
+++ b/libs/renderengine/gl/Program.h
@@ -44,7 +44,13 @@ public:
texCoords = 1,
/* Crop coordinates, in pixels */
- cropCoords = 2
+ cropCoords = 2,
+
+ /* Shadow color */
+ shadowColor = 3,
+
+ /* Shadow params */
+ shadowParams = 4,
};
Program(const ProgramCache::Key& needs, const char* vertex, const char* fragment);
diff --git a/libs/renderengine/include/renderengine/Mesh.h b/libs/renderengine/include/renderengine/Mesh.h
index 7618424e85..59db87ac97 100644
--- a/libs/renderengine/include/renderengine/Mesh.h
+++ b/libs/renderengine/include/renderengine/Mesh.h
@@ -26,13 +26,14 @@ namespace renderengine {
class Mesh {
public:
+ class Builder;
+
enum Primitive {
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() = default;
/*
@@ -43,12 +44,20 @@ public:
friend class Mesh;
float* mData;
size_t mStride;
+ size_t mOffset = 0;
VertexArray(float* data, size_t stride) : mData(data), mStride(stride) {}
+ // Returns a vertex array at an offset so its easier to append attributes from
+ // multiple sources.
+ VertexArray(VertexArray<TYPE>& other, size_t offset)
+ : mData(other.mData), mStride(other.mStride), mOffset(offset) {}
+
public:
- TYPE& operator[](size_t index) { return *reinterpret_cast<TYPE*>(&mData[index * mStride]); }
+ TYPE& operator[](size_t index) {
+ return *reinterpret_cast<TYPE*>(&mData[(index + mOffset) * mStride]);
+ }
TYPE const& operator[](size_t index) const {
- return *reinterpret_cast<TYPE const*>(&mData[index * mStride]);
+ return *reinterpret_cast<TYPE const*>(&mData[(index + mOffset) * mStride]);
}
};
@@ -67,6 +76,18 @@ public:
return VertexArray<TYPE>(getCropCoords(), mStride);
}
+ template <typename TYPE>
+ VertexArray<TYPE> getShadowColorArray() {
+ return VertexArray<TYPE>(getShadowColor(), mStride);
+ }
+
+ template <typename TYPE>
+ VertexArray<TYPE> getShadowParamsArray() {
+ return VertexArray<TYPE>(getShadowParams(), mStride);
+ }
+
+ uint16_t* getIndicesArray() { return getIndices(); }
+
Primitive getPrimitive() const;
// returns a pointer to the vertices positions
@@ -78,6 +99,15 @@ public:
// returns a pointer to the vertices crop coordinates
float const* getCropCoords() const;
+ // returns a pointer to colors
+ float const* getShadowColor() const;
+
+ // returns a pointer to the shadow params
+ float const* getShadowParams() const;
+
+ // returns a pointer to indices
+ uint16_t const* getIndices() const;
+
// number of vertices in this mesh
size_t getVertexCount() const;
@@ -87,6 +117,12 @@ public:
// dimension of texture coordinates
size_t getTexCoordsSize() const;
+ size_t getShadowParamsSize() const;
+
+ size_t getShadowColorSize() const;
+
+ size_t getIndexCount() const;
+
// return stride in bytes
size_t getByteStride() const;
@@ -94,6 +130,8 @@ public:
size_t getStride() const;
private:
+ Mesh(Primitive primitive, size_t vertexCount, size_t vertexSize, size_t texCoordSize,
+ size_t cropCoordsSize, size_t shadowColorSize, size_t shadowParamsSize, size_t indexCount);
Mesh(const Mesh&);
Mesh& operator=(const Mesh&);
Mesh const& operator=(const Mesh&) const;
@@ -101,13 +139,65 @@ private:
float* getPositions();
float* getTexCoords();
float* getCropCoords();
+ float* getShadowColor();
+ float* getShadowParams();
+ uint16_t* getIndices();
std::vector<float> mVertices;
size_t mVertexCount;
size_t mVertexSize;
size_t mTexCoordsSize;
+ size_t mCropCoordsSize;
+ size_t mShadowColorSize;
+ size_t mShadowParamsSize;
size_t mStride;
Primitive mPrimitive;
+ std::vector<uint16_t> mIndices;
+ size_t mIndexCount;
+};
+
+class Mesh::Builder {
+public:
+ Builder& setPrimitive(Primitive primitive) {
+ mPrimitive = primitive;
+ return *this;
+ };
+ Builder& setVertices(size_t vertexCount, size_t vertexSize) {
+ mVertexCount = vertexCount;
+ mVertexSize = vertexSize;
+ return *this;
+ };
+ Builder& setTexCoords(size_t texCoordsSize) {
+ mTexCoordsSize = texCoordsSize;
+ return *this;
+ };
+ Builder& setCropCoords(size_t cropCoordsSize) {
+ mCropCoordsSize = cropCoordsSize;
+ return *this;
+ };
+ Builder& setShadowAttrs() {
+ mShadowParamsSize = 3;
+ mShadowColorSize = 4;
+ return *this;
+ };
+ Builder& setIndices(size_t indexCount) {
+ mIndexCount = indexCount;
+ return *this;
+ };
+ Mesh build() const {
+ return Mesh{mPrimitive, mVertexCount, mVertexSize, mTexCoordsSize,
+ mCropCoordsSize, mShadowColorSize, mShadowParamsSize, mIndexCount};
+ }
+
+private:
+ size_t mVertexCount = 0;
+ size_t mVertexSize = 0;
+ size_t mTexCoordsSize = 0;
+ size_t mCropCoordsSize = 0;
+ size_t mShadowColorSize = 0;
+ size_t mShadowParamsSize = 0;
+ size_t mIndexCount = 0;
+ Primitive mPrimitive;
};
} // namespace renderengine
diff --git a/libs/renderengine/include/renderengine/private/Description.h b/libs/renderengine/include/renderengine/private/Description.h
index bad64c2f13..a62161a8a8 100644
--- a/libs/renderengine/include/renderengine/private/Description.h
+++ b/libs/renderengine/include/renderengine/private/Description.h
@@ -81,6 +81,9 @@ struct Description {
mat4 colorMatrix;
mat4 inputTransformMatrix;
mat4 outputTransformMatrix;
+
+ // True if this layer will draw a shadow.
+ bool drawShadows = false;
};
} // namespace renderengine