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

Commit 69e5adff authored by Chris Craik's avatar Chris Craik
Browse files

Define shadow casting behavior within layers

bug:15860114

Savelayers and HW layers both now support shadow casting.

For save layers, the light source should always be correct, for HW
layers, the light source position is set when the layer is created,
and updated when it is resized.

Change-Id: Ie85567dd43c2bb0a0b08fd0bd4db41efa793ac2b
parent e222e359
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -14,8 +14,6 @@
 * limitations under the License.
 */

#define LOG_TAG "RT-Animator"

#include "Animator.h"

#include <inttypes.h>
+24 −8
Original line number Diff line number Diff line
@@ -14,8 +14,6 @@
 * limitations under the License.
 */

#define LOG_TAG "DamageAccumulator"

#include "DamageAccumulator.h"

#include <cutils/log.h>
@@ -26,12 +24,6 @@
namespace android {
namespace uirenderer {

NullDamageAccumulator NullDamageAccumulator::sInstance;

NullDamageAccumulator* NullDamageAccumulator::instance() {
    return &sInstance;
}

enum TransformType {
    TransformInvalid = 0,
    TransformRenderNode,
@@ -60,6 +52,30 @@ DamageAccumulator::DamageAccumulator() {
    mHead->type = TransformNone;
}

static void computeTransformImpl(const DirtyStack* currentFrame, Matrix4* outMatrix) {
    if (currentFrame->prev != currentFrame) {
        computeTransformImpl(currentFrame->prev, outMatrix);
    }
    switch (currentFrame->type) {
    case TransformRenderNode:
        currentFrame->renderNode->applyViewPropertyTransforms(*outMatrix);
        break;
    case TransformMatrix4:
        outMatrix->multiply(*currentFrame->matrix4);
        break;
    case TransformNone:
        // nothing to be done
        break;
    default:
        LOG_ALWAYS_FATAL("Tried to compute transform with an invalid type: %d", currentFrame->type);
    }
}

void DamageAccumulator::computeCurrentTransform(Matrix4* outMatrix) const {
    outMatrix->loadIdentity();
    computeTransformImpl(mHead, outMatrix);
}

void DamageAccumulator::pushCommon() {
    if (!mHead->next) {
        DirtyStack* nextFrame = (DirtyStack*) mAllocator.alloc(sizeof(DirtyStack));
+8 −35
Original line number Diff line number Diff line
@@ -31,18 +31,7 @@ struct DirtyStack;
class RenderNode;
class Matrix4;

class IDamageAccumulator {
public:
    virtual void pushTransform(const RenderNode* transform) = 0;
    virtual void pushTransform(const Matrix4* transform) = 0;
    virtual void popTransform() = 0;
    virtual void dirty(float left, float top, float right, float bottom) = 0;
    virtual void peekAtDirty(SkRect* dest) = 0;
protected:
    virtual ~IDamageAccumulator() {}
};

class DamageAccumulator : public IDamageAccumulator {
class DamageAccumulator {
    PREVENT_COPY_AND_ASSIGN(DamageAccumulator);
public:
    DamageAccumulator();
@@ -51,17 +40,19 @@ public:
    // Push a transform node onto the stack. This should be called prior
    // to any dirty() calls. Subsequent calls to dirty()
    // will be affected by the transform when popTransform() is called.
    virtual void pushTransform(const RenderNode* transform);
    virtual void pushTransform(const Matrix4* transform);
    void pushTransform(const RenderNode* transform);
    void pushTransform(const Matrix4* transform);

    // Pops a transform node from the stack, propagating the dirty rect
    // up to the parent node. Returns the IDamageTransform that was just applied
    virtual void popTransform();
    void popTransform();

    virtual void dirty(float left, float top, float right, float bottom);
    void dirty(float left, float top, float right, float bottom);

    // Returns the current dirty area, *NOT* transformed by pushed transforms
    virtual void peekAtDirty(SkRect* dest);
    void peekAtDirty(SkRect* dest);

    void computeCurrentTransform(Matrix4* outMatrix) const;

    void finish(SkRect* totalDirty);

@@ -74,24 +65,6 @@ private:
    DirtyStack* mHead;
};

class NullDamageAccumulator : public IDamageAccumulator {
    PREVENT_COPY_AND_ASSIGN(NullDamageAccumulator);
public:
    virtual void pushTransform(const RenderNode* transform) { }
    virtual void pushTransform(const Matrix4* transform) { }
    virtual void popTransform() { }
    virtual void dirty(float left, float top, float right, float bottom) { }
    virtual void peekAtDirty(SkRect* dest) { dest->setEmpty(); }

    ANDROID_API static NullDamageAccumulator* instance();

private:
    NullDamageAccumulator() {}
    ~NullDamageAccumulator() {}

    static NullDamageAccumulator sInstance;
};

} /* namespace uirenderer */
} /* namespace android */

+1 −1
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ status_t DisplayListRenderer::prepareDirty(float left, float top,
            "prepareDirty called a second time during a recording!");
    mDisplayListData = new DisplayListData();

    initializeSaveStack(0, 0, getWidth(), getHeight());
    initializeSaveStack(0, 0, getWidth(), getHeight(), Vector3());

    mDirtyClip = opaque;
    mRestoreSaveCount = -1;
+16 −2
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ Layer::Layer(RenderState& renderState, const uint32_t layerWidth, const uint32_t
    deferredList = NULL;
    convexMask = NULL;
    caches.resourceCache.incrementRefcount(this);
    rendererLightPosDirty = true;
}

Layer::~Layer() {
@@ -80,6 +81,17 @@ void Layer::requireRenderer() {
    }
}

void Layer::updateLightPosFromRenderer(const OpenGLRenderer& rootRenderer) {
    if (renderer && rendererLightPosDirty) {
        // re-init renderer's light position, based upon last cached location in window
        Vector3 lightPos = rootRenderer.getLightCenter();
        cachedInvTransformInWindow.mapPoint3d(lightPos);
        renderer->initLight(lightPos, rootRenderer.getLightRadius(),
                rootRenderer.getAmbientShadowAlpha(), rootRenderer.getSpotShadowAlpha());
        rendererLightPosDirty = false;
    }
}

bool Layer::resize(const uint32_t width, const uint32_t height) {
    uint32_t desiredWidth = computeIdealWidth(width);
    uint32_t desiredHeight = computeIdealWidth(height);
@@ -203,7 +215,8 @@ void Layer::allocateTexture() {
    }
}

void Layer::defer() {
void Layer::defer(const OpenGLRenderer& rootRenderer) {
    updateLightPosFromRenderer(rootRenderer);
    const float width = layer.getWidth();
    const float height = layer.getHeight();

@@ -253,7 +266,8 @@ void Layer::flush() {
    }
}

void Layer::render() {
void Layer::render(const OpenGLRenderer& rootRenderer) {
    updateLightPosFromRenderer(rootRenderer);
    renderer->setViewport(layer.getWidth(), layer.getHeight());
    renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
            !isBlend());
Loading