Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 440992f6 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

[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
parent 0d4bd95f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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;
}

+49 −7
Original line number Diff line number Diff line
@@ -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
+43 −19
Original line number Diff line number Diff line
@@ -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,26 +1296,24 @@ void GLESRenderEngine::drawMesh(const Mesh& mesh) {
            managedState.outputTransferFunction =
                    Description::dataSpaceToTransferFunction(outputTransfer);
        }
    }

        ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext
                                                                   : mEGLContext,
    ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext : mEGLContext,
                                           managedState);

    if (mState.drawShadows) {
        glDrawElements(mesh.getPrimitive(), mesh.getIndexCount(), GL_UNSIGNED_SHORT,
                       mesh.getIndices());
    } else {
        glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
    }

        if (outputDebugPPMs) {
    if (mUseColorManagement && outputDebugPPMs) {
        static uint64_t managedColorFrameCount = 0;
        std::ostringstream out;
        out << "/data/texture_out" << managedColorFrameCount++;
        writePPM(out.str().c_str(), mVpWidth, mVpHeight);
    }
    } else {
        ProgramCache::getInstance().useProgram(mInProtectedContext ? mProtectedEGLContext
                                                                   : mEGLContext,
                                               mState);

        glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
    }

    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 {
+2 −0
Original line number Diff line number Diff line
@@ -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;
+7 −1
Original line number Diff line number Diff line
@@ -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);
Loading