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

Commit 16864cd9 authored by Nader Jawad's avatar Nader Jawad Committed by Android (Google) Code Review
Browse files

Merge "Updated HWUI to calculate the stretch bounds for a surface" into sc-dev

parents 49c3b39d bc341860
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -272,18 +272,21 @@ void DamageAccumulator::finish(SkRect* totalDirty) {

DamageAccumulator::StretchResult DamageAccumulator::findNearestStretchEffect() const {
    DirtyStack* frame = mHead;
    const auto& headProperties = mHead->renderNode->properties();
    float startWidth = headProperties.getWidth();
    float startHeight = headProperties.getHeight();
    while (frame->prev != frame) {
        if (frame->type == TransformRenderNode) {
            const auto& renderNode = frame->renderNode;
            const auto& frameRenderNodeProperties = renderNode->properties();
            const auto& effect =
                    frameRenderNodeProperties.layerProperties().getStretchEffect();
            const float width = (float) renderNode->getWidth();
            const float height = (float) renderNode->getHeight();
            const float width = (float) frameRenderNodeProperties.getWidth();
            const float height = (float) frameRenderNodeProperties.getHeight();
            if (!effect.isEmpty()) {
                Matrix4 stretchMatrix;
                computeTransformImpl(mHead, frame, &stretchMatrix);
                Rect stretchRect = Rect(0.f, 0.f, width, height);
                Rect stretchRect = Rect(0.f, 0.f, startWidth, startHeight);
                stretchMatrix.mapRect(stretchRect);

                return StretchResult{
+80 −5
Original line number Diff line number Diff line
@@ -68,9 +68,8 @@ static const SkString stretchShader = SkString(R"(
    // and the other way around.
    uniform float uInterpolationStrength;

    float easeInCubic(float t, float d) {
        float tmp = t * d;
        return tmp * tmp * tmp;
    float easeIn(float t, float d) {
        return t * d;
    }

    float computeOverscrollStart(
@@ -83,7 +82,7 @@ static const SkString stretchShader = SkString(R"(
    ) {
        float offsetPos = uStretchAffectedDist - inPos;
        float posBasedVariation = mix(
                1. ,easeInCubic(offsetPos, uInverseStretchAffectedDist), interpolationStrength);
                1. ,easeIn(offsetPos, uInverseStretchAffectedDist), interpolationStrength);
        float stretchIntensity = overscroll * posBasedVariation;
        return distanceStretched - (offsetPos / (1. + stretchIntensity));
    }
@@ -99,7 +98,7 @@ static const SkString stretchShader = SkString(R"(
    ) {
        float offsetPos = inPos - reverseStretchDist;
        float posBasedVariation = mix(
                1. ,easeInCubic(offsetPos, uInverseStretchAffectedDist), interpolationStrength);
                1. ,easeIn(offsetPos, uInverseStretchAffectedDist), interpolationStrength);
        float stretchIntensity = (-overscroll) * posBasedVariation;
        return 1 - (distanceStretched - (offsetPos / (1. + stretchIntensity)));
    }
@@ -234,4 +233,80 @@ sk_sp<SkRuntimeEffect> StretchEffect::getStretchEffect() {
    return instance.effect;
}

/**
 * Helper method that maps the input texture position to the stretch position
 * based on the given overscroll value that represents an overscroll from
 * either the top or left
 * @param overscroll current overscroll value
 * @param input normalized input position (can be x or y) on the input texture
 * @return stretched position of the input normalized from 0 to 1
 */
float reverseMapStart(float overscroll, float input) {
    float numerator = (-input * overscroll * overscroll) -
        (2 * input * overscroll) - input;
    float denominator = 1.f + (.3f * overscroll) +
        (.7f * input * overscroll * overscroll) + (.7f * input * overscroll);
    return -(numerator / denominator);
}

/**
 * Helper method that maps the input texture position to the stretch position
 * based on the given overscroll value that represents an overscroll from
 * either the bottom or right
 * @param overscroll current overscroll value
 * @param input normalized input position (can be x or y) on the input texture
 * @return stretched position of the input normalized from 0 to 1
 */
float reverseMapEnd(float overscroll, float input) {
    float numerator = (.3f * overscroll * overscroll) -
        (.3f * input * overscroll * overscroll) +
        (1.3f * input * overscroll) - overscroll - input;
    float denominator = (.7f * input * overscroll * overscroll) -
        (.7f * input * overscroll) - (.7f * overscroll * overscroll) +
        overscroll - 1.f;
    return numerator / denominator;
}

/**
  * Calculates the normalized stretch position given the normalized input
  * position. This handles calculating the overscroll from either the
  * top or left vs bottom or right depending on the sign of the given overscroll
  * value
  *
  * @param overscroll unit vector of overscroll from -1 to 1 indicating overscroll
  * from the bottom or right vs top or left respectively
  * @param normalizedInput the
  * @return
  */
float computeReverseOverscroll(float overscroll, float normalizedInput) {
    float distanceStretched = 1.f / (1.f + abs(overscroll));
    float distanceDiff = distanceStretched - 1.f;
    if (overscroll > 0) {
        float output = reverseMapStart(overscroll, normalizedInput);
        if (output <= 1.0f) {
            return output;
        } else if (output >= distanceStretched){
            return output - distanceDiff;
        }
    }

    if (overscroll < 0) {
        float output = reverseMapEnd(overscroll, normalizedInput);
        if (output >= 0.f) {
            return output;
        } else if (output < 0.f){
            return output + distanceDiff;
        }
    }
    return normalizedInput;
}

float StretchEffect::computeStretchedPositionX(float normalizedX) const {
  return computeReverseOverscroll(mStretchDirection.x(), normalizedX);
}

float StretchEffect::computeStretchedPositionY(float normalizedY) const {
  return computeReverseOverscroll(mStretchDirection.y(), normalizedY);
}

} // namespace android::uirenderer
 No newline at end of file
+16 −0
Original line number Diff line number Diff line
@@ -75,6 +75,22 @@ public:
        maxStretchAmountY = std::max(maxStretchAmountY, other.maxStretchAmountY);
    }

    /**
     * Return the stretched x position given the normalized x position with
     * the current horizontal stretch direction
     * @param normalizedX x position on the input texture from 0 to 1
     * @return x position when the horizontal stretch direction applied
     */
    float computeStretchedPositionX(float normalizedX) const;

    /**
     * Return the stretched y position given the normalized y position with
     * the current horizontal stretch direction
     * @param normalizedX y position on the input texture from 0 to 1
     * @return y position when the horizontal stretch direction applied
     */
    float computeStretchedPositionY(float normalizedY) const;

    sk_sp<SkShader> getShader(float width, float height,
                              const sk_sp<SkImage>& snapshotImage) const;

+31 −3
Original line number Diff line number Diff line
@@ -572,11 +572,11 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
            info.damageAccumulator->computeCurrentTransform(&transform);
            const RenderProperties& props = node.properties();

            uirenderer::Rect bounds(props.getWidth(), props.getHeight());
            if (info.stretchEffectCount) {
                handleStretchEffect(info, transform);
                handleStretchEffect(info, bounds);
            }

            uirenderer::Rect bounds(props.getWidth(), props.getHeight());
            transform.mapRect(bounds);

            if (CC_LIKELY(transform.isPureTranslate())) {
@@ -639,7 +639,33 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
            return env;
        }

        void handleStretchEffect(const TreeInfo& info, const Matrix4& transform) {
        void stretchTargetBounds(const StretchEffect& stretchEffect,
                                 float width, float height,
                                 const SkRect& childRelativeBounds,
                                 uirenderer::Rect& bounds) {
              float normalizedLeft = childRelativeBounds.left() / width;
              float normalizedTop = childRelativeBounds.top() / height;
              float normalizedRight = childRelativeBounds.right() / width;
              float normalizedBottom = childRelativeBounds.bottom() / height;
              float reverseLeft = width *
                  (stretchEffect.computeStretchedPositionX(normalizedLeft) -
                    normalizedLeft);
              float reverseTop = height *
                  (stretchEffect.computeStretchedPositionY(normalizedTop) -
                    normalizedTop);
              float reverseRight = width *
                  (stretchEffect.computeStretchedPositionX(normalizedRight) -
                    normalizedLeft);
              float reverseBottom = height *
                  (stretchEffect.computeStretchedPositionY(normalizedBottom) -
                    normalizedTop);
              bounds.left = reverseLeft;
              bounds.top = reverseTop;
              bounds.right = reverseRight;
              bounds.bottom = reverseBottom;
        }

        void handleStretchEffect(const TreeInfo& info, uirenderer::Rect& targetBounds) {
            // Search up to find the nearest stretcheffect parent
            const DamageAccumulator::StretchResult result =
                info.damageAccumulator->findNearestStretchEffect();
@@ -649,6 +675,8 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
            }

            const auto& childRelativeBounds = result.childRelativeBounds;
            stretchTargetBounds(*effect, result.width, result.height,
                                childRelativeBounds,targetBounds);

            JNIEnv* env = jnienv();