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

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

Merge "Fixed issue where SurfaceView transforms were applied twice" into udc-dev

parents 3f8673da af29d23e
Loading
Loading
Loading
Loading
+7 −36
Original line number Diff line number Diff line
@@ -207,27 +207,6 @@ static void applyTransforms(DirtyStack* frame, DirtyStack* end) {
    }
}

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

void DamageAccumulator::applyRenderNodeTransform(DirtyStack* frame) {
    if (frame->pendingDirty.isEmpty()) {
        return;
@@ -282,9 +261,6 @@ 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;
@@ -295,21 +271,16 @@ DamageAccumulator::StretchResult DamageAccumulator::findNearestStretchEffect() c
            const float height = (float) frameRenderNodeProperties.getHeight();
            if (!effect.isEmpty()) {
                Matrix4 stretchMatrix;
                computeTransformImpl(mHead, frame, &stretchMatrix);
                Rect stretchRect = Rect(0.f, 0.f, startWidth, startHeight);
                computeTransformImpl(frame, &stretchMatrix);
                Rect stretchRect = Rect(0.f, 0.f, width, height);
                stretchMatrix.mapRect(stretchRect);

                return StretchResult{
                        .stretchEffect = &effect,
                    .childRelativeBounds = SkRect::MakeLTRB(
                        stretchRect.left,
                        stretchRect.top,
                        stretchRect.right,
                        stretchRect.bottom
                    ),
                        .parentBounds = SkRect::MakeLTRB(stretchRect.left, stretchRect.top,
                                                         stretchRect.right, stretchRect.bottom),
                        .width = width,
                    .height = height
                };
                        .height = height};
            }
        }
        frame = frame->prev;
+2 −2
Original line number Diff line number Diff line
@@ -70,9 +70,9 @@ public:
        const StretchEffect* stretchEffect;

        /**
         * Bounds of the child relative to the stretch container
         * Bounds of the stretching container
         */
        const SkRect childRelativeBounds;
        const SkRect parentBounds;

        /**
         * Width of the stretch container
+36 −38
Original line number Diff line number Diff line
@@ -584,13 +584,15 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
            uirenderer::Rect bounds(props.getWidth(), props.getHeight());
            bool useStretchShader =
                    Properties::getStretchEffectBehavior() != StretchEffectBehavior::UniformScale;
            if (useStretchShader && info.stretchEffectCount) {
            // Compute the transform bounds first before calculating the stretch
            transform.mapRect(bounds);

            bool hasStretch = useStretchShader && info.stretchEffectCount;
            if (hasStretch) {
                handleStretchEffect(info, bounds);
            }

            transform.mapRect(bounds);

            if (CC_LIKELY(transform.isPureTranslate())) {
            if (CC_LIKELY(transform.isPureTranslate()) && !hasStretch) {
                // snap/round the computed bounds, so they match the rounding behavior
                // of the clear done in SurfaceView#draw().
                bounds.snapGeometryToPixelBoundaries(false);
@@ -665,45 +667,42 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
            return env;
        }

        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();
            const StretchEffect* effect = result.stretchEffect;
            if (!effect) {
            if (effect) {
                // Compute the number of pixels that the stretching container
                // scales by.
                // Then compute the scale factor that the child would need
                // to scale in order to occupy the same pixel bounds.
                auto& parentBounds = result.parentBounds;
                auto parentWidth = parentBounds.width();
                auto parentHeight = parentBounds.height();
                auto& stretchDirection = effect->getStretchDirection();
                auto stretchX = stretchDirection.x();
                auto stretchY = stretchDirection.y();
                auto stretchXPixels = parentWidth * std::abs(stretchX);
                auto stretchYPixels = parentHeight * std::abs(stretchY);
                SkMatrix stretchMatrix;

                auto childScaleX = 1 + (stretchXPixels / targetBounds.getWidth());
                auto childScaleY = 1 + (stretchYPixels / targetBounds.getHeight());
                auto pivotX = stretchX > 0 ? targetBounds.left : targetBounds.right;
                auto pivotY = stretchY > 0 ? targetBounds.top : targetBounds.bottom;
                stretchMatrix.setScale(childScaleX, childScaleY, pivotX, pivotY);
                SkRect rect = SkRect::MakeLTRB(targetBounds.left, targetBounds.top,
                                               targetBounds.right, targetBounds.bottom);
                SkRect dst = stretchMatrix.mapRect(rect);
                targetBounds.left = dst.left();
                targetBounds.top = dst.top();
                targetBounds.right = dst.right();
                targetBounds.bottom = dst.bottom();
            } else {
                return;
            }

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

            if (Properties::getStretchEffectBehavior() ==
                StretchEffectBehavior::Shader) {
                JNIEnv* env = jnienv();
@@ -714,9 +713,8 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
                        gPositionListener.clazz, gPositionListener.callApplyStretch, mListener,
                        info.canvasContext.getFrameNumber(), result.width, result.height,
                        stretchDirection.fX, stretchDirection.fY, effect->maxStretchAmountX,
                        effect->maxStretchAmountY, childRelativeBounds.left(),
                        childRelativeBounds.top(), childRelativeBounds.right(),
                        childRelativeBounds.bottom());
                        effect->maxStretchAmountY, targetBounds.left, targetBounds.top,
                        targetBounds.right, targetBounds.bottom);
                if (!keepListening) {
                    env->DeleteGlobalRef(mListener);
                    mListener = nullptr;