Loading libs/hwui/DamageAccumulator.cpp +7 −36 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading libs/hwui/DamageAccumulator.h +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading libs/hwui/jni/android_graphics_RenderNode.cpp +36 −38 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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; Loading Loading
libs/hwui/DamageAccumulator.cpp +7 −36 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading
libs/hwui/DamageAccumulator.h +2 −2 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/hwui/jni/android_graphics_RenderNode.cpp +36 −38 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -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(); Loading @@ -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; Loading