From c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Wed, 27 Aug 2014 15:34:52 -0700 Subject: Update transform isolation to handle command chunks bug:15570351 Prevent drawing transformations on a ViewGroup's canvas from directly affecting the transformation of the children through the renderer, since it's already baked into mTransformFromParent at record time. Change-Id: I6310a2260dfe4def0bde1fd2c5b93791a645d586 --- libs/hwui/RenderNode.cpp | 53 +++++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 37 deletions(-) (limited to 'libs/hwui/RenderNode.cpp') diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 658265d8335e..ac02349cd629 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -653,41 +653,12 @@ void RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds()); } -template -int RenderNode::issueOperationsOfNegZChildren( - const Vector& zTranslatedNodes, - OpenGLRenderer& renderer, T& handler) { - if (zTranslatedNodes.isEmpty()) return -1; - - // create a save around the body of the ViewGroup's draw method, so that - // matrix/clip methods don't affect composited children - int shadowSaveCount = renderer.getSaveCount(); - handler(new (handler.allocator()) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag), - PROPERTY_SAVECOUNT, properties().getClipToBounds()); - - issueOperationsOf3dChildren(zTranslatedNodes, kNegativeZChildren, renderer, handler); - return shadowSaveCount; -} - -template -void RenderNode::issueOperationsOfPosZChildren(int shadowRestoreTo, - const Vector& zTranslatedNodes, - OpenGLRenderer& renderer, T& handler) { - if (zTranslatedNodes.isEmpty()) return; - - LOG_ALWAYS_FATAL_IF(shadowRestoreTo < 0, "invalid save to restore to"); - handler(new (handler.allocator()) RestoreToCountOp(shadowRestoreTo), - PROPERTY_SAVECOUNT, properties().getClipToBounds()); - renderer.setOverrideLayerAlpha(1.0f); - - issueOperationsOf3dChildren(zTranslatedNodes, kPositiveZChildren, renderer, handler); -} - #define SHADOW_DELTA 0.1f template -void RenderNode::issueOperationsOf3dChildren(const Vector& zTranslatedNodes, - ChildrenSelectMode mode, OpenGLRenderer& renderer, T& handler) { +void RenderNode::issueOperationsOf3dChildren(ChildrenSelectMode mode, + const Matrix4& initialTransform, const Vector& zTranslatedNodes, + OpenGLRenderer& renderer, T& handler) { const int size = zTranslatedNodes.size(); if (size == 0 || (mode == kNegativeZChildren && zTranslatedNodes[0].key > 0.0f) @@ -696,6 +667,11 @@ void RenderNode::issueOperationsOf3dChildren(const Vector return; } + // Apply the base transform of the parent of the 3d children. This isolates + // 3d children of the current chunk from transformations made in previous chunks. + int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag); + renderer.setMatrix(initialTransform); + /** * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters * with very similar Z heights to draw together. @@ -750,6 +726,7 @@ void RenderNode::issueOperationsOf3dChildren(const Vector renderer.restoreToCount(restoreTo); drawIndex++; } + renderer.restoreToCount(rootRestoreTo); } template @@ -869,6 +846,8 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { bool quickRejected = properties().getClipToBounds() && renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight()); if (!quickRejected) { + Matrix4 initialTransform(*(renderer.currentTransform())); + if (drawLayer) { handler(new (alloc) DrawLayerOp(mLayer, 0, 0), renderer.getSaveCount() - 1, properties().getClipToBounds()); @@ -880,9 +859,9 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { Vector zTranslatedNodes; buildZSortedChildList(chunk, zTranslatedNodes); - // for 3d root, draw children with negative z values - int shadowRestoreTo = issueOperationsOfNegZChildren(zTranslatedNodes, - renderer, handler); + issueOperationsOf3dChildren(kNegativeZChildren, + initialTransform, zTranslatedNodes, renderer, handler); + const int saveCountOffset = renderer.getSaveCount() - 1; const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex; @@ -899,8 +878,8 @@ void RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { } } - // for 3d root, draw children with positive z values - issueOperationsOfPosZChildren(shadowRestoreTo, zTranslatedNodes, renderer, handler); + issueOperationsOf3dChildren(kPositiveZChildren, + initialTransform, zTranslatedNodes, renderer, handler); } } } -- cgit v1.2.3-59-g8ed1b