RenderNode.cpp revision 34bf49e4de4c1994b5d9c19166606bc9b7ad1b9c
1113e0824d6bddf4376240681f9cf6a2deded9498John Reck/* 2113e0824d6bddf4376240681f9cf6a2deded9498John Reck * Copyright (C) 2014 The Android Open Source Project 3113e0824d6bddf4376240681f9cf6a2deded9498John Reck * 4113e0824d6bddf4376240681f9cf6a2deded9498John Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5113e0824d6bddf4376240681f9cf6a2deded9498John Reck * you may not use this file except in compliance with the License. 6113e0824d6bddf4376240681f9cf6a2deded9498John Reck * You may obtain a copy of the License at 7113e0824d6bddf4376240681f9cf6a2deded9498John Reck * 8113e0824d6bddf4376240681f9cf6a2deded9498John Reck * http://www.apache.org/licenses/LICENSE-2.0 9113e0824d6bddf4376240681f9cf6a2deded9498John Reck * 10113e0824d6bddf4376240681f9cf6a2deded9498John Reck * Unless required by applicable law or agreed to in writing, software 11113e0824d6bddf4376240681f9cf6a2deded9498John Reck * distributed under the License is distributed on an "AS IS" BASIS, 12113e0824d6bddf4376240681f9cf6a2deded9498John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13113e0824d6bddf4376240681f9cf6a2deded9498John Reck * See the License for the specific language governing permissions and 14113e0824d6bddf4376240681f9cf6a2deded9498John Reck * limitations under the License. 15113e0824d6bddf4376240681f9cf6a2deded9498John Reck */ 16113e0824d6bddf4376240681f9cf6a2deded9498John Reck 17113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "RenderNode.h" 18113e0824d6bddf4376240681f9cf6a2deded9498John Reck 19e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck#include "DamageAccumulator.h" 20113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "Debug.h" 21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#if HWUI_NEW_OPS 220b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#include "BakedOpRenderer.h" 2391eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#include "RecordedOp.h" 2491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#include "OpDumper.h" 25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif 26113e0824d6bddf4376240681f9cf6a2deded9498John Reck#include "DisplayListOp.h" 2725fbb3fa1138675379102a44405852555cefccbdJohn Reck#include "LayerRenderer.h" 2825fbb3fa1138675379102a44405852555cefccbdJohn Reck#include "OpenGLRenderer.h" 292dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "TreeInfo.h" 30e0bb87d4bdbd3b08ab6a8569c8e564ed59b8a5a7Chris Craik#include "utils/MathUtils.h" 3170850ea258cbf91477efa57a1f1a23cc0044cc93Chris Craik#include "utils/TraceUtils.h" 32998a6d81896df8b662cc10ddeb35087b78b38d72John Reck#include "renderthread/CanvasContext.h" 33113e0824d6bddf4376240681f9cf6a2deded9498John Reck 34e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck#include "protos/hwui.pb.h" 35e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck#include "protos/ProtoHelpers.h" 36e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck 3777c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck#include <algorithm> 3877c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck#include <sstream> 3977c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck#include <string> 4077c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck 41113e0824d6bddf4376240681f9cf6a2deded9498John Recknamespace android { 42113e0824d6bddf4376240681f9cf6a2deded9498John Recknamespace uirenderer { 43113e0824d6bddf4376240681f9cf6a2deded9498John Reck 44443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reckvoid RenderNode::debugDumpLayers(const char* prefix) { 450b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if HWUI_NEW_OPS 460b7e8245db728d127ada698be63d78b33fc6e4daChris Craik LOG_ALWAYS_FATAL("TODO: dump layer"); 470b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#else 48443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck if (mLayer) { 49443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck ALOGD("%sNode %p (%s) has layer %p (fbo = %u, wasBuildLayered = %s)", 50443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck prefix, this, getName(), mLayer, mLayer->getFbo(), 51443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck mLayer->wasBuildLayered ? "true" : "false"); 52443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck } 530b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 54003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList) { 55b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (auto&& child : mDisplayList->getChildren()) { 5610ed692118552a01ff97b095295852b631e51beeChris Craik child->renderNode->debugDumpLayers(prefix); 57443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck } 58443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck } 59443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck} 60443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck 618de65a8e05285df52a1e6f0c1d5616dd233298a7John ReckRenderNode::RenderNode() 62ff941dcd815021bb20d6504eb486acb1e50592c3John Reck : mDirtyPropertyFields(0) 63003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik , mNeedsDisplayListSync(false) 64003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik , mDisplayList(nullptr) 65003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik , mStagingDisplayList(nullptr) 6668bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck , mAnimatorManager(*this) 67dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck , mParentCount(0) { 68113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 69113e0824d6bddf4376240681f9cf6a2deded9498John Reck 70113e0824d6bddf4376240681f9cf6a2deded9498John ReckRenderNode::~RenderNode() { 7144b49f070aafe8ad44efae87341121cce49ff11cJohn Reck deleteDisplayList(nullptr); 72003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik delete mStagingDisplayList; 730b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if HWUI_NEW_OPS 740b7e8245db728d127ada698be63d78b33fc6e4daChris Craik LOG_ALWAYS_FATAL_IF(mLayer, "layer missed detachment!"); 750b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#else 760e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck if (mLayer) { 770e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck ALOGW("Memory Warning: Layer %p missed its detachment, held on to for far too long!", mLayer); 780e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mLayer->postDecStrong(); 79d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mLayer = nullptr; 800e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck } 810b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 82113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 83113e0824d6bddf4376240681f9cf6a2deded9498John Reck 8451f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reckvoid RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* observer) { 85003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mNeedsDisplayListSync = true; 86003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik delete mStagingDisplayList; 87003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mStagingDisplayList = displayList; 889dea0d53f598d8fa98d9b50899fc9c7559f7a1a1John Reck // If mParentCount == 0 we are the sole reference to this RenderNode, 899dea0d53f598d8fa98d9b50899fc9c7559f7a1a1John Reck // so immediately free the old display list 909dea0d53f598d8fa98d9b50899fc9c7559f7a1a1John Reck if (!mParentCount && !mStagingDisplayList) { 9151f2d606dcbfba3cc5b03dfea37c1304b91c232fJohn Reck deleteDisplayList(observer); 929dea0d53f598d8fa98d9b50899fc9c7559f7a1a1John Reck } 93113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 94113e0824d6bddf4376240681f9cf6a2deded9498John Reck 95113e0824d6bddf4376240681f9cf6a2deded9498John Reck/** 96113e0824d6bddf4376240681f9cf6a2deded9498John Reck * This function is a simplified version of replay(), where we simply retrieve and log the 97113e0824d6bddf4376240681f9cf6a2deded9498John Reck * display list. This function should remain in sync with the replay() function. 98113e0824d6bddf4376240681f9cf6a2deded9498John Reck */ 9991eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#if HWUI_NEW_OPS 10091eff22b5d7f8fe551bae01331948858ce932a96Chris Craikvoid RenderNode::output(uint32_t level, const char* label) { 10191eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%s (%s %p%s%s%s%s%s)", 10291eff22b5d7f8fe551bae01331948858ce932a96Chris Craik label, 10391eff22b5d7f8fe551bae01331948858ce932a96Chris Craik getName(), 10491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik this, 10591eff22b5d7f8fe551bae01331948858ce932a96Chris Craik (MathUtils::isZero(properties().getAlpha()) ? ", zero alpha" : ""), 10691eff22b5d7f8fe551bae01331948858ce932a96Chris Craik (properties().hasShadow() ? ", casting shadow" : ""), 10791eff22b5d7f8fe551bae01331948858ce932a96Chris Craik (isRenderable() ? "" : ", empty"), 10891eff22b5d7f8fe551bae01331948858ce932a96Chris Craik (properties().getProjectBackwards() ? ", projected" : ""), 10991eff22b5d7f8fe551bae01331948858ce932a96Chris Craik (mLayer != nullptr ? ", on HW Layer" : "")); 11091eff22b5d7f8fe551bae01331948858ce932a96Chris Craik properties().debugOutputProperties(level + 1); 11191eff22b5d7f8fe551bae01331948858ce932a96Chris Craik 11291eff22b5d7f8fe551bae01331948858ce932a96Chris Craik if (mDisplayList) { 11391eff22b5d7f8fe551bae01331948858ce932a96Chris Craik for (auto&& op : mDisplayList->getOps()) { 11491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik std::stringstream strout; 11591eff22b5d7f8fe551bae01331948858ce932a96Chris Craik OpDumper::dump(*op, strout, level + 1); 11691eff22b5d7f8fe551bae01331948858ce932a96Chris Craik if (op->opId == RecordedOpId::RenderNodeOp) { 11791eff22b5d7f8fe551bae01331948858ce932a96Chris Craik auto rnOp = reinterpret_cast<const RenderNodeOp*>(op); 11891eff22b5d7f8fe551bae01331948858ce932a96Chris Craik rnOp->renderNode->output(level + 1, strout.str().c_str()); 11991eff22b5d7f8fe551bae01331948858ce932a96Chris Craik } else { 12091eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%s", strout.str().c_str()); 12191eff22b5d7f8fe551bae01331948858ce932a96Chris Craik } 12291eff22b5d7f8fe551bae01331948858ce932a96Chris Craik } 12391eff22b5d7f8fe551bae01331948858ce932a96Chris Craik } 12491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik ALOGD("%*s/RenderNode(%s %p)", level * 2, "", getName(), this); 12591eff22b5d7f8fe551bae01331948858ce932a96Chris Craik} 12691eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#else 127113e0824d6bddf4376240681f9cf6a2deded9498John Reckvoid RenderNode::output(uint32_t level) { 128bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik ALOGD("%*sStart display list (%p, %s%s%s%s%s%s)", (level - 1) * 2, "", this, 129b5a5435a77bae40b55053ccde93b1ed45d0e8329Chris Craik getName(), 13043a1d31a2837406a437937b340db85c1a05ed1edChris Craik (MathUtils::isZero(properties().getAlpha()) ? ", zero alpha" : ""), 131b5a5435a77bae40b55053ccde93b1ed45d0e8329Chris Craik (properties().hasShadow() ? ", casting shadow" : ""), 132b5a5435a77bae40b55053ccde93b1ed45d0e8329Chris Craik (isRenderable() ? "" : ", empty"), 133bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik (properties().getProjectBackwards() ? ", projected" : ""), 134d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik (mLayer != nullptr ? ", on HW Layer" : "")); 135eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita ALOGD("%*s%s %d", level * 2, "", "Save", SaveFlags::MatrixClip); 136d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck properties().debugOutputProperties(level); 137003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList) { 1388afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // TODO: consider printing the chunk boundaries here 139003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik for (auto&& op : mDisplayList->getOps()) { 14010ed692118552a01ff97b095295852b631e51beeChris Craik op->output(level, DisplayListOp::kOpLogFlag_Recurse); 141dc0349bebafb486b044655f3c146450b527a5123John Reck } 142113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 1433f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, getName()); 14491eff22b5d7f8fe551bae01331948858ce932a96Chris Craik } 14591eff22b5d7f8fe551bae01331948858ce932a96Chris Craik#endif 146113e0824d6bddf4376240681f9cf6a2deded9498John Reck 147e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reckvoid RenderNode::copyTo(proto::RenderNode *pnode) { 148e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pnode->set_id(static_cast<uint64_t>( 149e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck reinterpret_cast<uintptr_t>(this))); 150e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pnode->set_name(mName.string(), mName.length()); 151e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck 152e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck proto::RenderProperties* pprops = pnode->mutable_properties(); 153e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_left(properties().getLeft()); 154e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_top(properties().getTop()); 155e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_right(properties().getRight()); 156e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_bottom(properties().getBottom()); 157e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_clip_flags(properties().getClippingFlags()); 158e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_alpha(properties().getAlpha()); 159e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_translation_x(properties().getTranslationX()); 160e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_translation_y(properties().getTranslationY()); 161e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_translation_z(properties().getTranslationZ()); 162e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_elevation(properties().getElevation()); 163e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_rotation(properties().getRotation()); 164e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_rotation_x(properties().getRotationX()); 165e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_rotation_y(properties().getRotationY()); 166e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_scale_x(properties().getScaleX()); 167e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_scale_y(properties().getScaleY()); 168e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_pivot_x(properties().getPivotX()); 169e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_pivot_y(properties().getPivotY()); 170e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_has_overlapping_rendering(properties().getHasOverlappingRendering()); 171e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_pivot_explicitly_set(properties().isPivotExplicitlySet()); 172e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_project_backwards(properties().getProjectBackwards()); 173e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->set_projection_receiver(properties().isProjectionReceiver()); 174e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck set(pprops->mutable_clip_bounds(), properties().getClipBounds()); 175e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck 176e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck const Outline& outline = properties().getOutline(); 177e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck if (outline.getType() != Outline::Type::None) { 178e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck proto::Outline* poutline = pprops->mutable_outline(); 179e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck poutline->clear_path(); 180e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck if (outline.getType() == Outline::Type::Empty) { 181e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck poutline->set_type(proto::Outline_Type_Empty); 182e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } else if (outline.getType() == Outline::Type::ConvexPath) { 183e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck poutline->set_type(proto::Outline_Type_ConvexPath); 184e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck if (const SkPath* path = outline.getPath()) { 185e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck set(poutline->mutable_path(), *path); 186e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } 187e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } else if (outline.getType() == Outline::Type::RoundRect) { 188e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck poutline->set_type(proto::Outline_Type_RoundRect); 189e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } else { 190e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck ALOGW("Uknown outline type! %d", static_cast<int>(outline.getType())); 191e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck poutline->set_type(proto::Outline_Type_None); 192e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } 193e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck poutline->set_should_clip(outline.getShouldClip()); 194e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck poutline->set_alpha(outline.getAlpha()); 195e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck poutline->set_radius(outline.getRadius()); 196e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck set(poutline->mutable_bounds(), outline.getBounds()); 197e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } else { 198e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->clear_outline(); 199e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } 200e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck 201e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck const RevealClip& revealClip = properties().getRevealClip(); 202e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck if (revealClip.willClip()) { 203e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck proto::RevealClip* prevealClip = pprops->mutable_reveal_clip(); 204e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck prevealClip->set_x(revealClip.getX()); 205e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck prevealClip->set_y(revealClip.getY()); 206e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck prevealClip->set_radius(revealClip.getRadius()); 207e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } else { 208e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pprops->clear_reveal_clip(); 209e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } 210e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck 211e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck pnode->clear_children(); 212003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList) { 213b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (auto&& child : mDisplayList->getChildren()) { 214b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik child->renderNode->copyTo(pnode->add_children()); 215e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } 216e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck } 217e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck} 218e248bd1b2c3fcf8088429507e73b31f45ee2544bJohn Reck 219fe5e7b7346a54537b980796ceeca66bfdbd05561John Reckint RenderNode::getDebugSize() { 220fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck int size = sizeof(RenderNode); 221003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mStagingDisplayList) { 222003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik size += mStagingDisplayList->getUsedSize(); 223fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck } 224003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList && mDisplayList != mStagingDisplayList) { 225003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik size += mDisplayList->getUsedSize(); 226fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck } 227fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck return size; 228fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck} 229fe5e7b7346a54537b980796ceeca66bfdbd05561John Reck 230f4198b713e43c0c0f9adac74203cf24c2a49b802John Reckvoid RenderNode::prepareTree(TreeInfo& info) { 231f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck ATRACE_CALL(); 23269e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik LOG_ALWAYS_FATAL_IF(!info.damageAccumulator, "DamageAccumulator missing"); 233f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck 234a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik // Functors don't correctly handle stencil usage of overdraw debugging - shove 'em in a layer. 235a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik bool functorsNeedLayer = Properties::debugOverdraw; 236a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik 237a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik prepareTreeImpl(info, functorsNeedLayer); 238f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck} 239f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck 24068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reckvoid RenderNode::addAnimator(const sp<BaseRenderNodeAnimator>& animator) { 24168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck mAnimatorManager.addAnimator(animator); 24268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck} 24368bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck 2448b083206aef627b6445a8c6be8bf5bb1d778a7f8Doris Liuvoid RenderNode::removeAnimator(const sp<BaseRenderNodeAnimator>& animator) { 2458b083206aef627b6445a8c6be8bf5bb1d778a7f8Doris Liu mAnimatorManager.removeAnimator(animator); 2468b083206aef627b6445a8c6be8bf5bb1d778a7f8Doris Liu} 2478b083206aef627b6445a8c6be8bf5bb1d778a7f8Doris Liu 248e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reckvoid RenderNode::damageSelf(TreeInfo& info) { 249ce9f308063cc2bc7851f3f58c881da8a7271eeccJohn Reck if (isRenderable()) { 250293e868bfc1b07aad2cb2ebeee5b07424852c510John Reck if (properties().getClipDamageToBounds()) { 251a447d29c65fb811cd184775a3476101a1cede929John Reck info.damageAccumulator->dirty(0, 0, properties().getWidth(), properties().getHeight()); 252a447d29c65fb811cd184775a3476101a1cede929John Reck } else { 253a447d29c65fb811cd184775a3476101a1cede929John Reck // Hope this is big enough? 254a447d29c65fb811cd184775a3476101a1cede929John Reck // TODO: Get this from the display list ops or something 255c128823940fb0be96eda810fa9f0c75f66d944b0John Reck info.damageAccumulator->dirty(DIRTY_MIN, DIRTY_MIN, DIRTY_MAX, DIRTY_MAX); 256a447d29c65fb811cd184775a3476101a1cede929John Reck } 257e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck } 258e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck} 259e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck 260a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reckvoid RenderNode::prepareLayer(TreeInfo& info, uint32_t dirtyMask) { 261856f0cc3e382206e67c1a62fe878627d7dd9ada5Chris Craik LayerType layerType = properties().effectiveLayerType(); 262182952f5eeefc2a21d76d4664ada0e2d78c1105cChris Craik if (CC_UNLIKELY(layerType == LayerType::RenderLayer)) { 263a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck // Damage applied so far needs to affect our parent, but does not require 264a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck // the layer to be updated. So we pop/push here to clear out the current 265a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck // damage and get a clean state for display list or children updates to 266a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck // affect, which will require the layer to be updated 267a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck info.damageAccumulator->popTransform(); 268a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck info.damageAccumulator->pushTransform(this); 269a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck if (dirtyMask & DISPLAY_LIST) { 270a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck damageSelf(info); 271a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck } 27225fbb3fa1138675379102a44405852555cefccbdJohn Reck } 27325fbb3fa1138675379102a44405852555cefccbdJohn Reck} 27425fbb3fa1138675379102a44405852555cefccbdJohn Reck 2759fded232a9548a304e0145011df8849fba0dcda7Chris Craikstatic layer_t* createLayer(RenderState& renderState, uint32_t width, uint32_t height) { 2760b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if HWUI_NEW_OPS 2779fded232a9548a304e0145011df8849fba0dcda7Chris Craik return renderState.layerPool().get(renderState, width, height); 2780b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#else 2790b7e8245db728d127ada698be63d78b33fc6e4daChris Craik return LayerRenderer::createRenderLayer(renderState, width, height); 2800b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 2810b7e8245db728d127ada698be63d78b33fc6e4daChris Craik} 2820b7e8245db728d127ada698be63d78b33fc6e4daChris Craik 2839fded232a9548a304e0145011df8849fba0dcda7Chris Craikstatic void destroyLayer(layer_t* layer) { 2840b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if HWUI_NEW_OPS 2859fded232a9548a304e0145011df8849fba0dcda7Chris Craik RenderState& renderState = layer->renderState; 2869fded232a9548a304e0145011df8849fba0dcda7Chris Craik renderState.layerPool().putOrDelete(layer); 2870b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#else 2880b7e8245db728d127ada698be63d78b33fc6e4daChris Craik LayerRenderer::destroyLayer(layer); 2890b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 2900b7e8245db728d127ada698be63d78b33fc6e4daChris Craik} 2910b7e8245db728d127ada698be63d78b33fc6e4daChris Craik 2929fded232a9548a304e0145011df8849fba0dcda7Chris Craikstatic bool layerMatchesWidthAndHeight(layer_t* layer, int width, int height) { 2939fded232a9548a304e0145011df8849fba0dcda7Chris Craik#if HWUI_NEW_OPS 2949fded232a9548a304e0145011df8849fba0dcda7Chris Craik return layer->viewportWidth == (uint32_t) width && layer->viewportHeight == (uint32_t)height; 2959fded232a9548a304e0145011df8849fba0dcda7Chris Craik#else 2969fded232a9548a304e0145011df8849fba0dcda7Chris Craik return layer->layer.getWidth() == width && layer->layer.getHeight() == height; 2979fded232a9548a304e0145011df8849fba0dcda7Chris Craik#endif 2989fded232a9548a304e0145011df8849fba0dcda7Chris Craik} 2999fded232a9548a304e0145011df8849fba0dcda7Chris Craik 30025fbb3fa1138675379102a44405852555cefccbdJohn Reckvoid RenderNode::pushLayerUpdate(TreeInfo& info) { 301856f0cc3e382206e67c1a62fe878627d7dd9ada5Chris Craik LayerType layerType = properties().effectiveLayerType(); 30225fbb3fa1138675379102a44405852555cefccbdJohn Reck // If we are not a layer OR we cannot be rendered (eg, view was detached) 30325fbb3fa1138675379102a44405852555cefccbdJohn Reck // we need to destroy any Layers we may have had previously 304182952f5eeefc2a21d76d4664ada0e2d78c1105cChris Craik if (CC_LIKELY(layerType != LayerType::RenderLayer) || CC_UNLIKELY(!isRenderable())) { 30525fbb3fa1138675379102a44405852555cefccbdJohn Reck if (CC_UNLIKELY(mLayer)) { 3060b7e8245db728d127ada698be63d78b33fc6e4daChris Craik destroyLayer(mLayer); 307d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mLayer = nullptr; 30825fbb3fa1138675379102a44405852555cefccbdJohn Reck } 30925fbb3fa1138675379102a44405852555cefccbdJohn Reck return; 31025fbb3fa1138675379102a44405852555cefccbdJohn Reck } 31125fbb3fa1138675379102a44405852555cefccbdJohn Reck 31269e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik bool transformUpdateNeeded = false; 31325fbb3fa1138675379102a44405852555cefccbdJohn Reck if (!mLayer) { 3149fded232a9548a304e0145011df8849fba0dcda7Chris Craik mLayer = createLayer(info.canvasContext.getRenderState(), getWidth(), getHeight()); 315f559bd1e679cc268bfa796b3c46acbd4783755a2Chris Craik#if !HWUI_NEW_OPS 316f559bd1e679cc268bfa796b3c46acbd4783755a2Chris Craik applyLayerPropertiesToLayer(info); 317f559bd1e679cc268bfa796b3c46acbd4783755a2Chris Craik#endif 3189fded232a9548a304e0145011df8849fba0dcda7Chris Craik damageSelf(info); 3199fded232a9548a304e0145011df8849fba0dcda7Chris Craik transformUpdateNeeded = true; 3209fded232a9548a304e0145011df8849fba0dcda7Chris Craik } else if (!layerMatchesWidthAndHeight(mLayer, getWidth(), getHeight())) { 3210b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if HWUI_NEW_OPS 322d4fe4d3b30aaefcaaae6a6d1b8dc4bf59e034768Chris Craik // TODO: remove now irrelevant, currently enqueued damage (respecting damage ordering) 323d4fe4d3b30aaefcaaae6a6d1b8dc4bf59e034768Chris Craik // Or, ideally, maintain damage between frames on node/layer so ordering is always correct 3249fded232a9548a304e0145011df8849fba0dcda7Chris Craik RenderState& renderState = mLayer->renderState; 3259fded232a9548a304e0145011df8849fba0dcda7Chris Craik if (properties().fitsOnLayer()) { 3269fded232a9548a304e0145011df8849fba0dcda7Chris Craik mLayer = renderState.layerPool().resize(mLayer, getWidth(), getHeight()); 3279fded232a9548a304e0145011df8849fba0dcda7Chris Craik } else { 3280b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#else 329c25e506f7fc08790c0532f927f31310a2ca778b7John Reck if (!LayerRenderer::resizeLayer(mLayer, getWidth(), getHeight())) { 3300b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 3310b7e8245db728d127ada698be63d78b33fc6e4daChris Craik destroyLayer(mLayer); 332d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mLayer = nullptr; 333c25e506f7fc08790c0532f927f31310a2ca778b7John Reck } 33425fbb3fa1138675379102a44405852555cefccbdJohn Reck damageSelf(info); 33569e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik transformUpdateNeeded = true; 33669e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik } 33769e5adffb19135d51bde8e458f4907d7265f3e23Chris Craik 33825fbb3fa1138675379102a44405852555cefccbdJohn Reck SkRect dirty; 33925fbb3fa1138675379102a44405852555cefccbdJohn Reck info.damageAccumulator->peekAtDirty(&dirty); 34025fbb3fa1138675379102a44405852555cefccbdJohn Reck 341c25e506f7fc08790c0532f927f31310a2ca778b7John Reck if (!mLayer) { 3420e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck Caches::getInstance().dumpMemoryUsage(); 343c25e506f7fc08790c0532f927f31310a2ca778b7John Reck if (info.errorHandler) { 34477c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck std::ostringstream err; 34577c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck err << "Unable to create layer for " << getName(); 34676caecf421b42e9b8294a65f62ff2d90b55a337bChris Craik const int maxTextureSize = Caches::getInstance().maxTextureSize; 34777c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck if (getWidth() > maxTextureSize || getHeight() > maxTextureSize) { 34877c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck err << ", size " << getWidth() << "x" << getHeight() 34977c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck << " exceeds max size " << maxTextureSize; 35077c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck } else { 35177c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck err << ", see logcat for more info"; 35277c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck } 35377c40109cf25d29f85ee6c13aeb96e22e55f33abJohn Reck info.errorHandler->onError(err.str()); 354c25e506f7fc08790c0532f927f31310a2ca778b7John Reck } 355c25e506f7fc08790c0532f927f31310a2ca778b7John Reck return; 356c25e506f7fc08790c0532f927f31310a2ca778b7John Reck } 357c25e506f7fc08790c0532f927f31310a2ca778b7John Reck 35898787e6c9b2c10b1ab7820bdac168686025b924aChris Craik if (transformUpdateNeeded && mLayer) { 359c71bfcaa182e3d4fd9874362d3b4781fda934a21Chris Craik // update the transform in window of the layer to reset its origin wrt light source position 360c71bfcaa182e3d4fd9874362d3b4781fda934a21Chris Craik Matrix4 windowTransform; 361c71bfcaa182e3d4fd9874362d3b4781fda934a21Chris Craik info.damageAccumulator->computeCurrentTransform(&windowTransform); 362c71bfcaa182e3d4fd9874362d3b4781fda934a21Chris Craik mLayer->setWindowTransform(windowTransform); 363c71bfcaa182e3d4fd9874362d3b4781fda934a21Chris Craik } 364c79eabcd3c6306bb2ec75f9584b79e661f265127John Reck 3650b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if HWUI_NEW_OPS 3660b7e8245db728d127ada698be63d78b33fc6e4daChris Craik info.layerUpdateQueue->enqueueLayerWithDamage(this, dirty); 3670b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#else 368c79eabcd3c6306bb2ec75f9584b79e661f265127John Reck if (dirty.intersect(0, 0, getWidth(), getHeight())) { 36971487eb0ceb2b7dea02649e78d99bb5952f5eaefMike Reed dirty.roundOut(&dirty); 37025fbb3fa1138675379102a44405852555cefccbdJohn Reck mLayer->updateDeferred(this, dirty.fLeft, dirty.fTop, dirty.fRight, dirty.fBottom); 37125fbb3fa1138675379102a44405852555cefccbdJohn Reck } 37225fbb3fa1138675379102a44405852555cefccbdJohn Reck // This is not inside the above if because we may have called 37325fbb3fa1138675379102a44405852555cefccbdJohn Reck // updateDeferred on a previous prepare pass that didn't have a renderer 37425fbb3fa1138675379102a44405852555cefccbdJohn Reck if (info.renderer && mLayer->deferredUpdateScheduled) { 37525fbb3fa1138675379102a44405852555cefccbdJohn Reck info.renderer->pushLayerUpdate(mLayer); 37625fbb3fa1138675379102a44405852555cefccbdJohn Reck } 3770b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 378998a6d81896df8b662cc10ddeb35087b78b38d72John Reck 379e2e53a7079733694bd52dbce665e9ceff21e9727Chris Craik // There might be prefetched layers that need to be accounted for. 380e2e53a7079733694bd52dbce665e9ceff21e9727Chris Craik // That might be us, so tell CanvasContext that this layer is in the 381e2e53a7079733694bd52dbce665e9ceff21e9727Chris Craik // tree and should not be destroyed. 382e2e53a7079733694bd52dbce665e9ceff21e9727Chris Craik info.canvasContext.markLayerInUse(this); 38325fbb3fa1138675379102a44405852555cefccbdJohn Reck} 38425fbb3fa1138675379102a44405852555cefccbdJohn Reck 385a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik/** 386a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * Traverse down the the draw tree to prepare for a frame. 387a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * 388a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * MODE_FULL = UI Thread-driven (thus properties must be synced), otherwise RT driven 389a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * 390a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * While traversing down the tree, functorsNeedLayer flag is set to true if anything that uses the 391a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik * stencil buffer may be needed. Views that use a functor to draw will be forced onto a layer. 392a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik */ 393a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craikvoid RenderNode::prepareTreeImpl(TreeInfo& info, bool functorsNeedLayer) { 394a447d29c65fb811cd184775a3476101a1cede929John Reck info.damageAccumulator->pushTransform(this); 395f47a594f5250b1914c36423ee6b371f0b8db09d0John Reck 396dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck if (info.mode == TreeInfo::MODE_FULL) { 39725fbb3fa1138675379102a44405852555cefccbdJohn Reck pushStagingPropertiesChanges(info); 398e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck } 3999eb9f6f8cbbbd87d45da8071aa54cb066a797723John Reck uint32_t animatorDirtyMask = 0; 4009eb9f6f8cbbbd87d45da8071aa54cb066a797723John Reck if (CC_LIKELY(info.runAnimations)) { 4019eb9f6f8cbbbd87d45da8071aa54cb066a797723John Reck animatorDirtyMask = mAnimatorManager.animate(info); 4029eb9f6f8cbbbd87d45da8071aa54cb066a797723John Reck } 403a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik 4043f725f0a5abd23833176bdc26fda964e923e75deJohn Reck bool willHaveFunctor = false; 405003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (info.mode == TreeInfo::MODE_FULL && mStagingDisplayList) { 406b36af87f8275f4b982906f88193ec27600f2746aChris Craik willHaveFunctor = !mStagingDisplayList->getFunctors().empty(); 407003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik } else if (mDisplayList) { 408b36af87f8275f4b982906f88193ec27600f2746aChris Craik willHaveFunctor = !mDisplayList->getFunctors().empty(); 4093f725f0a5abd23833176bdc26fda964e923e75deJohn Reck } 410a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik bool childFunctorsNeedLayer = mProperties.prepareForFunctorPresence( 411a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik willHaveFunctor, functorsNeedLayer); 412a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik 413f648108f83d4e74811919e9811efb8fcc184b8a3John Reck if (CC_UNLIKELY(mPositionListener.get())) { 414f648108f83d4e74811919e9811efb8fcc184b8a3John Reck mPositionListener->onPositionUpdated(*this, info); 415f648108f83d4e74811919e9811efb8fcc184b8a3John Reck } 416f648108f83d4e74811919e9811efb8fcc184b8a3John Reck 417a7c2ea20c43ab797bef5801530687e22e83def8fJohn Reck prepareLayer(info, animatorDirtyMask); 418dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck if (info.mode == TreeInfo::MODE_FULL) { 41925fbb3fa1138675379102a44405852555cefccbdJohn Reck pushStagingDisplayListChanges(info); 42025fbb3fa1138675379102a44405852555cefccbdJohn Reck } 421003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik prepareSubTree(info, childFunctorsNeedLayer, mDisplayList); 42225fbb3fa1138675379102a44405852555cefccbdJohn Reck pushLayerUpdate(info); 42325fbb3fa1138675379102a44405852555cefccbdJohn Reck 424a447d29c65fb811cd184775a3476101a1cede929John Reck info.damageAccumulator->popTransform(); 425f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck} 426f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck 427b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikvoid RenderNode::syncProperties() { 428b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik mProperties = mStagingProperties; 429b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 430b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 43125fbb3fa1138675379102a44405852555cefccbdJohn Reckvoid RenderNode::pushStagingPropertiesChanges(TreeInfo& info) { 432ff941dcd815021bb20d6504eb486acb1e50592c3John Reck // Push the animators first so that setupStartValueIfNecessary() is called 433ff941dcd815021bb20d6504eb486acb1e50592c3John Reck // before properties() is trampled by stagingProperties(), as they are 434ff941dcd815021bb20d6504eb486acb1e50592c3John Reck // required by some animators. 4359eb9f6f8cbbbd87d45da8071aa54cb066a797723John Reck if (CC_LIKELY(info.runAnimations)) { 436119907cd2575c56b1ebf66348b52e67aaf6a88d8John Reck mAnimatorManager.pushStaging(); 4379eb9f6f8cbbbd87d45da8071aa54cb066a797723John Reck } 438ff941dcd815021bb20d6504eb486acb1e50592c3John Reck if (mDirtyPropertyFields) { 439ff941dcd815021bb20d6504eb486acb1e50592c3John Reck mDirtyPropertyFields = 0; 440e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck damageSelf(info); 441a447d29c65fb811cd184775a3476101a1cede929John Reck info.damageAccumulator->popTransform(); 442b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik syncProperties(); 4430b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if !HWUI_NEW_OPS 44425fbb3fa1138675379102a44405852555cefccbdJohn Reck applyLayerPropertiesToLayer(info); 4450b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 446e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck // We could try to be clever and only re-damage if the matrix changed. 447e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck // However, we don't need to worry about that. The cost of over-damaging 448e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck // here is only going to be a single additional map rect of this node 449e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck // plus a rect join(). The parent's transform (and up) will only be 450e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck // performed once. 451a447d29c65fb811cd184775a3476101a1cede929John Reck info.damageAccumulator->pushTransform(this); 452e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck damageSelf(info); 453ff941dcd815021bb20d6504eb486acb1e50592c3John Reck } 45425fbb3fa1138675379102a44405852555cefccbdJohn Reck} 45525fbb3fa1138675379102a44405852555cefccbdJohn Reck 4560b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if !HWUI_NEW_OPS 45764bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampevoid RenderNode::applyLayerPropertiesToLayer(TreeInfo& info) { 45825fbb3fa1138675379102a44405852555cefccbdJohn Reck if (CC_LIKELY(!mLayer)) return; 45925fbb3fa1138675379102a44405852555cefccbdJohn Reck 46025fbb3fa1138675379102a44405852555cefccbdJohn Reck const LayerProperties& props = properties().layerProperties(); 46125fbb3fa1138675379102a44405852555cefccbdJohn Reck mLayer->setAlpha(props.alpha(), props.xferMode()); 46225fbb3fa1138675379102a44405852555cefccbdJohn Reck mLayer->setColorFilter(props.colorFilter()); 46325fbb3fa1138675379102a44405852555cefccbdJohn Reck mLayer->setBlend(props.needsBlending()); 46425fbb3fa1138675379102a44405852555cefccbdJohn Reck} 4650b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 46625fbb3fa1138675379102a44405852555cefccbdJohn Reck 46734bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reckvoid RenderNode::syncDisplayList(TreeInfo* info) { 468b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // Make sure we inc first so that we don't fluctuate between 0 and 1, 469b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik // which would thrash the layer cache 470003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mStagingDisplayList) { 471b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (auto&& child : mStagingDisplayList->getChildren()) { 472b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik child->renderNode->incParentRefCount(); 473b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 474b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 47534bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck deleteDisplayList(info ? info->observer : nullptr, info); 476003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mDisplayList = mStagingDisplayList; 477003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mStagingDisplayList = nullptr; 478003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList) { 479cd1c3eba69d044b551cededad75474038f919890John Reck for (auto& iter : mDisplayList->getFunctors()) { 480cd1c3eba69d044b551cededad75474038f919890John Reck (*iter.functor)(DrawGlInfo::kModeSync, nullptr); 481b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 4821d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu for (size_t i = 0; i < mDisplayList->getPushStagingFunctors().size(); i++) { 4831d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu (*mDisplayList->getPushStagingFunctors()[i])(); 4841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu } 485b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 486b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 487b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 48825fbb3fa1138675379102a44405852555cefccbdJohn Reckvoid RenderNode::pushStagingDisplayListChanges(TreeInfo& info) { 489003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mNeedsDisplayListSync) { 490003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mNeedsDisplayListSync = false; 4915c9d717d3e7064db76d2a01223af51379dadf2c3John Reck // Damage with the old display list first then the new one to catch any 4925c9d717d3e7064db76d2a01223af51379dadf2c3John Reck // changes in isRenderable or, in the future, bounds 4935c9d717d3e7064db76d2a01223af51379dadf2c3John Reck damageSelf(info); 49434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck syncDisplayList(&info); 495e4267ea4f20740c37c01bfb6aefcf61fddc4566aJohn Reck damageSelf(info); 4968de65a8e05285df52a1e6f0c1d5616dd233298a7John Reck } 4978de65a8e05285df52a1e6f0c1d5616dd233298a7John Reck} 498113e0824d6bddf4376240681f9cf6a2deded9498John Reck 49934bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reckvoid RenderNode::deleteDisplayList(TreeObserver* observer, TreeInfo* info) { 500003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList) { 501b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (auto&& child : mDisplayList->getChildren()) { 50234bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck child->renderNode->decParentRefCount(observer, info); 503dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck } 504dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck } 505003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik delete mDisplayList; 506003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik mDisplayList = nullptr; 507dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck} 508dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck 509003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craikvoid RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayList* subtree) { 5108de65a8e05285df52a1e6f0c1d5616dd233298a7John Reck if (subtree) { 511860d155f866cc15a725e7ce03763280987f24901John Reck TextureCache& cache = Caches::getInstance().textureCache; 512b36af87f8275f4b982906f88193ec27600f2746aChris Craik info.out.hasFunctors |= subtree->getFunctors().size(); 513b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (auto&& bitmapResource : subtree->getBitmapResources()) { 514e2e53a7079733694bd52dbce665e9ceff21e9727Chris Craik void* ownerToken = &info.canvasContext; 515e2e53a7079733694bd52dbce665e9ceff21e9727Chris Craik info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource); 516f4198b713e43c0c0f9adac74203cf24c2a49b802John Reck } 517b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (auto&& op : subtree->getChildren()) { 518b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik RenderNode* childNode = op->renderNode; 519b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#if HWUI_NEW_OPS 520b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik info.damageAccumulator->pushTransform(&op->localMatrix); 521b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik bool childFunctorsNeedLayer = functorsNeedLayer; // TODO! || op->mRecordedWithPotentialStencilClip; 522b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#else 5238d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik info.damageAccumulator->pushTransform(&op->localMatrix); 524a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik bool childFunctorsNeedLayer = functorsNeedLayer 525a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik // Recorded with non-rect clip, or canvas-rotated by parent 526a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik || op->mRecordedWithPotentialStencilClip; 527b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif 528a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik childNode->prepareTreeImpl(info, childFunctorsNeedLayer); 529a447d29c65fb811cd184775a3476101a1cede929John Reck info.damageAccumulator->popTransform(); 5305bf11bb98f5dbe278c257355d24c181237abd68cJohn Reck } 531113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 532113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 533113e0824d6bddf4376240681f9cf6a2deded9498John Reck 53434bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reckvoid RenderNode::destroyHardwareResources(TreeObserver* observer, TreeInfo* info) { 535dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck if (mLayer) { 5360b7e8245db728d127ada698be63d78b33fc6e4daChris Craik destroyLayer(mLayer); 537d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mLayer = nullptr; 538dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck } 539003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList) { 540b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (auto&& child : mDisplayList->getChildren()) { 54134bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck child->renderNode->destroyHardwareResources(observer, info); 542dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck } 543003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mNeedsDisplayListSync) { 544dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck // Next prepare tree we are going to push a new display list, so we can 545dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck // drop our current one now 54634bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck deleteDisplayList(observer, info); 547dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck } 548dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck } 549dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck} 550dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck 55134bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reckvoid RenderNode::decParentRefCount(TreeObserver* observer, TreeInfo* info) { 552dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck LOG_ALWAYS_FATAL_IF(!mParentCount, "already 0!"); 553dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck mParentCount--; 554dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck if (!mParentCount) { 55544b49f070aafe8ad44efae87341121cce49ff11cJohn Reck if (observer) { 55644b49f070aafe8ad44efae87341121cce49ff11cJohn Reck observer->onMaybeRemovedFromTree(this); 55744b49f070aafe8ad44efae87341121cce49ff11cJohn Reck } 55834bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck if (CC_UNLIKELY(mPositionListener.get())) { 55934bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck mPositionListener->onPositionLost(*this, info); 56034bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck } 561dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck // If a child of ours is being attached to our parent then this will incorrectly 562dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck // destroy its hardware resources. However, this situation is highly unlikely 563dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck // and the failure is "just" that the layer is re-created, so this should 564dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck // be safe enough 56534bf49e4de4c1994b5d9c19166606bc9b7ad1b9cJohn Reck destroyHardwareResources(observer, info); 566dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck } 567dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck} 568dcba6725e8b9d3eba9ad7a01258d6aa974feafbaJohn Reck 569113e0824d6bddf4376240681f9cf6a2deded9498John Reck/* 570113e0824d6bddf4376240681f9cf6a2deded9498John Reck * For property operations, we pass a savecount of 0, since the operations aren't part of the 571113e0824d6bddf4376240681f9cf6a2deded9498John Reck * displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in 572d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck * base saveCount (i.e., how RestoreToCount uses saveCount + properties().getCount()) 573113e0824d6bddf4376240681f9cf6a2deded9498John Reck */ 574113e0824d6bddf4376240681f9cf6a2deded9498John Reck#define PROPERTY_SAVECOUNT 0 575113e0824d6bddf4376240681f9cf6a2deded9498John Reck 576113e0824d6bddf4376240681f9cf6a2deded9498John Recktemplate <class T> 577b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craikvoid RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler) { 578113e0824d6bddf4376240681f9cf6a2deded9498John Reck#if DEBUG_DISPLAY_LIST 579b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik properties().debugOutputProperties(handler.level() + 1); 580113e0824d6bddf4376240681f9cf6a2deded9498John Reck#endif 581d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (properties().getLeft() != 0 || properties().getTop() != 0) { 582d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck renderer.translate(properties().getLeft(), properties().getTop()); 583113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 584d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (properties().getStaticMatrix()) { 585139088228faa7f3c446af7387e017933998a5570Derek Sollenberger renderer.concatMatrix(*properties().getStaticMatrix()); 586d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } else if (properties().getAnimationMatrix()) { 587139088228faa7f3c446af7387e017933998a5570Derek Sollenberger renderer.concatMatrix(*properties().getAnimationMatrix()); 588113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 589f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck if (properties().hasTransformMatrix()) { 590f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck if (properties().isTransformTranslateOnly()) { 591d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck renderer.translate(properties().getTranslationX(), properties().getTranslationY()); 592113e0824d6bddf4376240681f9cf6a2deded9498John Reck } else { 593d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck renderer.concatMatrix(*properties().getTransformMatrix()); 594113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 595113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 596856f0cc3e382206e67c1a62fe878627d7dd9ada5Chris Craik const bool isLayer = properties().effectiveLayerType() != LayerType::None; 597a753f4c6cb8558795e673df1896532cd148781e2Chris Craik int clipFlags = properties().getClippingFlags(); 598d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (properties().getAlpha() < 1) { 59925fbb3fa1138675379102a44405852555cefccbdJohn Reck if (isLayer) { 600a753f4c6cb8558795e673df1896532cd148781e2Chris Craik clipFlags &= ~CLIP_TO_BOUNDS; // bounds clipping done by layer 601113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 6024e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik if (CC_LIKELY(isLayer || !properties().getHasOverlappingRendering())) { 6034e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik // simply scale rendering content's alpha 6044e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik renderer.scaleAlpha(properties().getAlpha()); 6054e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik } else { 6064e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik // savelayer needed to create an offscreen buffer 6074e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik Rect layerBounds(0, 0, getWidth(), getHeight()); 6084e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik if (clipFlags) { 6094e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik properties().getClippingRectForFlags(clipFlags, &layerBounds); 6104e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik clipFlags = 0; // all clipping done by savelayer 6114e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik } 6124e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik SaveLayerOp* op = new (handler.allocator()) SaveLayerOp( 6134e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik layerBounds.left, layerBounds.top, 6144e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik layerBounds.right, layerBounds.bottom, 6154e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik (int) (properties().getAlpha() * 255), 616eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita SaveFlags::HasAlphaLayer | SaveFlags::ClipToLayer); 6174e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds()); 6184e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik } 6191a0808e64c170fa7b620b858fa5875f6f08a2b54Chris Craik 6201a0808e64c170fa7b620b858fa5875f6f08a2b54Chris Craik if (CC_UNLIKELY(ATRACE_ENABLED() && properties().promotedToLayer())) { 6214e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik // pretend alpha always causes savelayer to warn about 6224e9d9b2a590105035c29f12ecf0689333e6b55e7Chris Craik // performance problem affecting old versions 6231a0808e64c170fa7b620b858fa5875f6f08a2b54Chris Craik ATRACE_FORMAT("%s alpha caused saveLayer %dx%d", getName(), 6241a0808e64c170fa7b620b858fa5875f6f08a2b54Chris Craik static_cast<int>(getWidth()), 6251a0808e64c170fa7b620b858fa5875f6f08a2b54Chris Craik static_cast<int>(getHeight())); 6261a0808e64c170fa7b620b858fa5875f6f08a2b54Chris Craik } 627113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 628a753f4c6cb8558795e673df1896532cd148781e2Chris Craik if (clipFlags) { 629a753f4c6cb8558795e673df1896532cd148781e2Chris Craik Rect clipRect; 630a753f4c6cb8558795e673df1896532cd148781e2Chris Craik properties().getClippingRectForFlags(clipFlags, &clipRect); 6318c271ca63b62061fd22cfee78fd6a574b44476fdChris Craik ClipRectOp* op = new (handler.allocator()) ClipRectOp( 632a753f4c6cb8558795e673df1896532cd148781e2Chris Craik clipRect.left, clipRect.top, clipRect.right, clipRect.bottom, 633a753f4c6cb8558795e673df1896532cd148781e2Chris Craik SkRegion::kIntersect_Op); 634d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck handler(op, PROPERTY_SAVECOUNT, properties().getClipToBounds()); 635113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 6368c271ca63b62061fd22cfee78fd6a574b44476fdChris Craik 637e83cbd451868a734bfac07ccd680d5617080b579Chris Craik // TODO: support nesting round rect clips 638af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik if (mProperties.getRevealClip().willClip()) { 639af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik Rect bounds; 640af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik mProperties.getRevealClip().getBounds(&bounds); 641af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik renderer.setClippingRoundRect(handler.allocator(), bounds, mProperties.getRevealClip().getRadius()); 642af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik } else if (mProperties.getOutline().willClip()) { 643af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik renderer.setClippingOutline(handler.allocator(), &(mProperties.getOutline())); 644113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 645113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 646113e0824d6bddf4376240681f9cf6a2deded9498John Reck 647113e0824d6bddf4376240681f9cf6a2deded9498John Reck/** 648113e0824d6bddf4376240681f9cf6a2deded9498John Reck * Apply property-based transformations to input matrix 649113e0824d6bddf4376240681f9cf6a2deded9498John Reck * 650113e0824d6bddf4376240681f9cf6a2deded9498John Reck * If true3dTransform is set to true, the transform applied to the input matrix will use true 4x4 651113e0824d6bddf4376240681f9cf6a2deded9498John Reck * matrix computation instead of the Skia 3x3 matrix + camera hackery. 652113e0824d6bddf4376240681f9cf6a2deded9498John Reck */ 65369e5adffb19135d51bde8e458f4907d7265f3e23Chris Craikvoid RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) const { 654d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (properties().getLeft() != 0 || properties().getTop() != 0) { 655d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck matrix.translate(properties().getLeft(), properties().getTop()); 656113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 657d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (properties().getStaticMatrix()) { 658d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck mat4 stat(*properties().getStaticMatrix()); 659113e0824d6bddf4376240681f9cf6a2deded9498John Reck matrix.multiply(stat); 660d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } else if (properties().getAnimationMatrix()) { 661d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck mat4 anim(*properties().getAnimationMatrix()); 662113e0824d6bddf4376240681f9cf6a2deded9498John Reck matrix.multiply(anim); 663113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 664e0bb87d4bdbd3b08ab6a8569c8e564ed59b8a5a7Chris Craik 665cc39e16cb98855f35079941b5e7e6eac2b7bc388Chris Craik bool applyTranslationZ = true3dTransform && !MathUtils::isZero(properties().getZ()); 666e0bb87d4bdbd3b08ab6a8569c8e564ed59b8a5a7Chris Craik if (properties().hasTransformMatrix() || applyTranslationZ) { 667f7483e3af0513a1baa8341d403df2e0c0896a9ffJohn Reck if (properties().isTransformTranslateOnly()) { 668d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck matrix.translate(properties().getTranslationX(), properties().getTranslationY(), 669cc39e16cb98855f35079941b5e7e6eac2b7bc388Chris Craik true3dTransform ? properties().getZ() : 0.0f); 670113e0824d6bddf4376240681f9cf6a2deded9498John Reck } else { 671113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (!true3dTransform) { 672d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck matrix.multiply(*properties().getTransformMatrix()); 673113e0824d6bddf4376240681f9cf6a2deded9498John Reck } else { 674113e0824d6bddf4376240681f9cf6a2deded9498John Reck mat4 true3dMat; 675113e0824d6bddf4376240681f9cf6a2deded9498John Reck true3dMat.loadTranslate( 676d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck properties().getPivotX() + properties().getTranslationX(), 677d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck properties().getPivotY() + properties().getTranslationY(), 678cc39e16cb98855f35079941b5e7e6eac2b7bc388Chris Craik properties().getZ()); 679d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck true3dMat.rotate(properties().getRotationX(), 1, 0, 0); 680d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck true3dMat.rotate(properties().getRotationY(), 0, 1, 0); 681d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck true3dMat.rotate(properties().getRotation(), 0, 0, 1); 682d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck true3dMat.scale(properties().getScaleX(), properties().getScaleY(), 1); 683d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck true3dMat.translate(-properties().getPivotX(), -properties().getPivotY()); 684113e0824d6bddf4376240681f9cf6a2deded9498John Reck 685113e0824d6bddf4376240681f9cf6a2deded9498John Reck matrix.multiply(true3dMat); 686113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 687113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 688113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 689113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 690113e0824d6bddf4376240681f9cf6a2deded9498John Reck 691113e0824d6bddf4376240681f9cf6a2deded9498John Reck/** 692113e0824d6bddf4376240681f9cf6a2deded9498John Reck * Organizes the DisplayList hierarchy to prepare for background projection reordering. 693113e0824d6bddf4376240681f9cf6a2deded9498John Reck * 694113e0824d6bddf4376240681f9cf6a2deded9498John Reck * This should be called before a call to defer() or drawDisplayList() 695113e0824d6bddf4376240681f9cf6a2deded9498John Reck * 696113e0824d6bddf4376240681f9cf6a2deded9498John Reck * Each DisplayList that serves as a 3d root builds its list of composited children, 697113e0824d6bddf4376240681f9cf6a2deded9498John Reck * which are flagged to not draw in the standard draw loop. 698113e0824d6bddf4376240681f9cf6a2deded9498John Reck */ 699113e0824d6bddf4376240681f9cf6a2deded9498John Reckvoid RenderNode::computeOrdering() { 700113e0824d6bddf4376240681f9cf6a2deded9498John Reck ATRACE_CALL(); 701113e0824d6bddf4376240681f9cf6a2deded9498John Reck mProjectedNodes.clear(); 702113e0824d6bddf4376240681f9cf6a2deded9498John Reck 703113e0824d6bddf4376240681f9cf6a2deded9498John Reck // TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that 704113e0824d6bddf4376240681f9cf6a2deded9498John Reck // transform properties are applied correctly to top level children 705003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList == nullptr) return; 706b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (unsigned int i = 0; i < mDisplayList->getChildren().size(); i++) { 7078d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik renderNodeOp_t* childOp = mDisplayList->getChildren()[i]; 708b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik childOp->renderNode->computeOrderingImpl(childOp, &mProjectedNodes, &mat4::identity()); 709113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 710113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 711113e0824d6bddf4376240681f9cf6a2deded9498John Reck 712113e0824d6bddf4376240681f9cf6a2deded9498John Reckvoid RenderNode::computeOrderingImpl( 7138d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik renderNodeOp_t* opState, 7148d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik std::vector<renderNodeOp_t*>* compositedChildrenOfProjectionSurface, 715113e0824d6bddf4376240681f9cf6a2deded9498John Reck const mat4* transformFromProjectionSurface) { 716113e0824d6bddf4376240681f9cf6a2deded9498John Reck mProjectedNodes.clear(); 717003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList == nullptr || mDisplayList->isEmpty()) return; 718113e0824d6bddf4376240681f9cf6a2deded9498John Reck 719113e0824d6bddf4376240681f9cf6a2deded9498John Reck // TODO: should avoid this calculation in most cases 720113e0824d6bddf4376240681f9cf6a2deded9498John Reck // TODO: just calculate single matrix, down to all leaf composited elements 721113e0824d6bddf4376240681f9cf6a2deded9498John Reck Matrix4 localTransformFromProjectionSurface(*transformFromProjectionSurface); 7228d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik localTransformFromProjectionSurface.multiply(opState->localMatrix); 723113e0824d6bddf4376240681f9cf6a2deded9498John Reck 724d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (properties().getProjectBackwards()) { 725113e0824d6bddf4376240681f9cf6a2deded9498John Reck // composited projectee, flag for out of order draw, save matrix, and store in proj surface 7268d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik opState->skipInOrderDraw = true; 7278d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik opState->transformFromCompositingAncestor = localTransformFromProjectionSurface; 728272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck compositedChildrenOfProjectionSurface->push_back(opState); 729113e0824d6bddf4376240681f9cf6a2deded9498John Reck } else { 730113e0824d6bddf4376240681f9cf6a2deded9498John Reck // standard in order draw 7318d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik opState->skipInOrderDraw = false; 732113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 733113e0824d6bddf4376240681f9cf6a2deded9498John Reck 734b36af87f8275f4b982906f88193ec27600f2746aChris Craik if (mDisplayList->getChildren().size() > 0) { 735003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik const bool isProjectionReceiver = mDisplayList->projectionReceiveIndex >= 0; 736113e0824d6bddf4376240681f9cf6a2deded9498John Reck bool haveAppliedPropertiesToProjection = false; 737b36af87f8275f4b982906f88193ec27600f2746aChris Craik for (unsigned int i = 0; i < mDisplayList->getChildren().size(); i++) { 7388d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik renderNodeOp_t* childOp = mDisplayList->getChildren()[i]; 739b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik RenderNode* child = childOp->renderNode; 740113e0824d6bddf4376240681f9cf6a2deded9498John Reck 7418d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik std::vector<renderNodeOp_t*>* projectionChildren = nullptr; 742d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik const mat4* projectionTransform = nullptr; 743d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck if (isProjectionReceiver && !child->properties().getProjectBackwards()) { 744bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik // if receiving projections, collect projecting descendant 745113e0824d6bddf4376240681f9cf6a2deded9498John Reck 746bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik // Note that if a direct descendant is projecting backwards, we pass its 747bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik // grandparent projection collection, since it shouldn't project onto its 748113e0824d6bddf4376240681f9cf6a2deded9498John Reck // parent, where it will already be drawing. 749113e0824d6bddf4376240681f9cf6a2deded9498John Reck projectionChildren = &mProjectedNodes; 750113e0824d6bddf4376240681f9cf6a2deded9498John Reck projectionTransform = &mat4::identity(); 751113e0824d6bddf4376240681f9cf6a2deded9498John Reck } else { 752113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (!haveAppliedPropertiesToProjection) { 753113e0824d6bddf4376240681f9cf6a2deded9498John Reck applyViewPropertyTransforms(localTransformFromProjectionSurface); 754113e0824d6bddf4376240681f9cf6a2deded9498John Reck haveAppliedPropertiesToProjection = true; 755113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 756113e0824d6bddf4376240681f9cf6a2deded9498John Reck projectionChildren = compositedChildrenOfProjectionSurface; 757113e0824d6bddf4376240681f9cf6a2deded9498John Reck projectionTransform = &localTransformFromProjectionSurface; 758113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 759f293259c0d7331892dfc87180f813ccfd0101c09Derek Sollenberger child->computeOrderingImpl(childOp, projectionChildren, projectionTransform); 760113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 761113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 762113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 763113e0824d6bddf4376240681f9cf6a2deded9498John Reck 764113e0824d6bddf4376240681f9cf6a2deded9498John Reckclass DeferOperationHandler { 765113e0824d6bddf4376240681f9cf6a2deded9498John Reckpublic: 766113e0824d6bddf4376240681f9cf6a2deded9498John Reck DeferOperationHandler(DeferStateStruct& deferStruct, int level) 767113e0824d6bddf4376240681f9cf6a2deded9498John Reck : mDeferStruct(deferStruct), mLevel(level) {} 768113e0824d6bddf4376240681f9cf6a2deded9498John Reck inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) { 769113e0824d6bddf4376240681f9cf6a2deded9498John Reck operation->defer(mDeferStruct, saveCount, mLevel, clipToBounds); 770113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 771113e0824d6bddf4376240681f9cf6a2deded9498John Reck inline LinearAllocator& allocator() { return *(mDeferStruct.mAllocator); } 77264bb413a664001c95c8439cf097dc3033f4ed733Andreas Gampe inline void startMark(const char* name) {} // do nothing 773b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik inline void endMark() {} 774b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik inline int level() { return mLevel; } 775b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik inline int replayFlags() { return mDeferStruct.mReplayFlags; } 7767466986d2055eb8711f36a85ac539b1572ffe805Chris Craik inline SkPath* allocPathForFrame() { return mDeferStruct.allocPathForFrame(); } 777113e0824d6bddf4376240681f9cf6a2deded9498John Reck 778113e0824d6bddf4376240681f9cf6a2deded9498John Reckprivate: 779113e0824d6bddf4376240681f9cf6a2deded9498John Reck DeferStateStruct& mDeferStruct; 780113e0824d6bddf4376240681f9cf6a2deded9498John Reck const int mLevel; 781113e0824d6bddf4376240681f9cf6a2deded9498John Reck}; 782113e0824d6bddf4376240681f9cf6a2deded9498John Reck 78380d4902196899d1325cd9f52c06ae0174cf9bd4cChris Craikvoid RenderNode::defer(DeferStateStruct& deferStruct, const int level) { 784113e0824d6bddf4376240681f9cf6a2deded9498John Reck DeferOperationHandler handler(deferStruct, level); 785b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik issueOperations<DeferOperationHandler>(deferStruct.mRenderer, handler); 786113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 787113e0824d6bddf4376240681f9cf6a2deded9498John Reck 788113e0824d6bddf4376240681f9cf6a2deded9498John Reckclass ReplayOperationHandler { 789113e0824d6bddf4376240681f9cf6a2deded9498John Reckpublic: 790113e0824d6bddf4376240681f9cf6a2deded9498John Reck ReplayOperationHandler(ReplayStateStruct& replayStruct, int level) 791113e0824d6bddf4376240681f9cf6a2deded9498John Reck : mReplayStruct(replayStruct), mLevel(level) {} 792113e0824d6bddf4376240681f9cf6a2deded9498John Reck inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) { 793113e0824d6bddf4376240681f9cf6a2deded9498John Reck#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS 7943f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik mReplayStruct.mRenderer.eventMark(operation->name()); 795113e0824d6bddf4376240681f9cf6a2deded9498John Reck#endif 796113e0824d6bddf4376240681f9cf6a2deded9498John Reck operation->replay(mReplayStruct, saveCount, mLevel, clipToBounds); 797113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 798113e0824d6bddf4376240681f9cf6a2deded9498John Reck inline LinearAllocator& allocator() { return *(mReplayStruct.mAllocator); } 799b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik inline void startMark(const char* name) { 800b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik mReplayStruct.mRenderer.startMark(name); 801b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik } 802b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik inline void endMark() { 803b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik mReplayStruct.mRenderer.endMark(); 804b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik } 805b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik inline int level() { return mLevel; } 806b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik inline int replayFlags() { return mReplayStruct.mReplayFlags; } 8077466986d2055eb8711f36a85ac539b1572ffe805Chris Craik inline SkPath* allocPathForFrame() { return mReplayStruct.allocPathForFrame(); } 808113e0824d6bddf4376240681f9cf6a2deded9498John Reck 809113e0824d6bddf4376240681f9cf6a2deded9498John Reckprivate: 810113e0824d6bddf4376240681f9cf6a2deded9498John Reck ReplayStateStruct& mReplayStruct; 811113e0824d6bddf4376240681f9cf6a2deded9498John Reck const int mLevel; 812113e0824d6bddf4376240681f9cf6a2deded9498John Reck}; 813113e0824d6bddf4376240681f9cf6a2deded9498John Reck 81480d4902196899d1325cd9f52c06ae0174cf9bd4cChris Craikvoid RenderNode::replay(ReplayStateStruct& replayStruct, const int level) { 815b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik ReplayOperationHandler handler(replayStruct, level); 816b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik issueOperations<ReplayOperationHandler>(replayStruct.mRenderer, handler); 817113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 818113e0824d6bddf4376240681f9cf6a2deded9498John Reck 819003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craikvoid RenderNode::buildZSortedChildList(const DisplayList::Chunk& chunk, 820272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes) { 821b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#if !HWUI_NEW_OPS 8228afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (chunk.beginChildIndex == chunk.endChildIndex) return; 823113e0824d6bddf4376240681f9cf6a2deded9498John Reck 8248afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik for (unsigned int i = chunk.beginChildIndex; i < chunk.endChildIndex; i++) { 825b36af87f8275f4b982906f88193ec27600f2746aChris Craik DrawRenderNodeOp* childOp = mDisplayList->getChildren()[i]; 826b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik RenderNode* child = childOp->renderNode; 827cc39e16cb98855f35079941b5e7e6eac2b7bc388Chris Craik float childZ = child->properties().getZ(); 828113e0824d6bddf4376240681f9cf6a2deded9498John Reck 8298afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik if (!MathUtils::isZero(childZ) && chunk.reorderChildren) { 830272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck zTranslatedNodes.push_back(ZDrawRenderNodeOpPair(childZ, childOp)); 8318d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik childOp->skipInOrderDraw = true; 832d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck } else if (!child->properties().getProjectBackwards()) { 833113e0824d6bddf4376240681f9cf6a2deded9498John Reck // regular, in order drawing DisplayList 8348d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik childOp->skipInOrderDraw = false; 835113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 836113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 837113e0824d6bddf4376240681f9cf6a2deded9498John Reck 8388afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik // Z sort any 3d children (stable-ness makes z compare fall back to standard drawing order) 839113e0824d6bddf4376240681f9cf6a2deded9498John Reck std::stable_sort(zTranslatedNodes.begin(), zTranslatedNodes.end()); 840b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif 841113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 842113e0824d6bddf4376240681f9cf6a2deded9498John Reck 843b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craiktemplate <class T> 844b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craikvoid RenderNode::issueDrawShadowOperation(const Matrix4& transformFromParent, T& handler) { 84577b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik if (properties().getAlpha() <= 0.0f 84677b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik || properties().getOutline().getAlpha() <= 0.0f 8478d0ec389531d071529fb0a800f10733b057205d9Teng-Hui Zhu || !properties().getOutline().getPath() 8488d0ec389531d071529fb0a800f10733b057205d9Teng-Hui Zhu || properties().getScaleX() == 0 8498d0ec389531d071529fb0a800f10733b057205d9Teng-Hui Zhu || properties().getScaleY() == 0) { 85077b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik // no shadow to draw 85177b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik return; 85277b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik } 853b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik 854b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik mat4 shadowMatrixXY(transformFromParent); 855b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik applyViewPropertyTransforms(shadowMatrixXY); 856b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik 857b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik // Z matrix needs actual 3d transformation, so mapped z values will be correct 858b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik mat4 shadowMatrixZ(transformFromParent); 859b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik applyViewPropertyTransforms(shadowMatrixZ, true); 860b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik 8617466986d2055eb8711f36a85ac539b1572ffe805Chris Craik const SkPath* casterOutlinePath = properties().getOutline().getPath(); 862af4d04cab6d48ae0d6a5e79bd30f679af87abaadChris Craik const SkPath* revealClipPath = properties().getRevealClip().getPath(); 86361317325b7b4b4ffafd9400ab5966e8d7c67df2eChris Craik if (revealClipPath && revealClipPath->isEmpty()) return; 86461317325b7b4b4ffafd9400ab5966e8d7c67df2eChris Craik 86577b5cad3efedd20f2b7cc14d87ccce1b0261960aChris Craik float casterAlpha = properties().getAlpha() * properties().getOutline().getAlpha(); 8667466986d2055eb8711f36a85ac539b1572ffe805Chris Craik 867faa79ff9d964de940660d2226d5b06ded9294597Chris Craik 868faa79ff9d964de940660d2226d5b06ded9294597Chris Craik // holds temporary SkPath to store the result of intersections 869d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik SkPath* frameAllocatedPath = nullptr; 8707466986d2055eb8711f36a85ac539b1572ffe805Chris Craik const SkPath* outlinePath = casterOutlinePath; 871faa79ff9d964de940660d2226d5b06ded9294597Chris Craik 872faa79ff9d964de940660d2226d5b06ded9294597Chris Craik // intersect the outline with the reveal clip, if present 8737466986d2055eb8711f36a85ac539b1572ffe805Chris Craik if (revealClipPath) { 874faa79ff9d964de940660d2226d5b06ded9294597Chris Craik frameAllocatedPath = handler.allocPathForFrame(); 875faa79ff9d964de940660d2226d5b06ded9294597Chris Craik 87602a26300fb129608eb1df8cf31c14a5a5d8bd6edTom Hudson Op(*outlinePath, *revealClipPath, kIntersect_SkPathOp, frameAllocatedPath); 877faa79ff9d964de940660d2226d5b06ded9294597Chris Craik outlinePath = frameAllocatedPath; 878faa79ff9d964de940660d2226d5b06ded9294597Chris Craik } 879faa79ff9d964de940660d2226d5b06ded9294597Chris Craik 880faa79ff9d964de940660d2226d5b06ded9294597Chris Craik // intersect the outline with the clipBounds, if present 881faa79ff9d964de940660d2226d5b06ded9294597Chris Craik if (properties().getClippingFlags() & CLIP_TO_CLIP_BOUNDS) { 882faa79ff9d964de940660d2226d5b06ded9294597Chris Craik if (!frameAllocatedPath) { 883faa79ff9d964de940660d2226d5b06ded9294597Chris Craik frameAllocatedPath = handler.allocPathForFrame(); 884faa79ff9d964de940660d2226d5b06ded9294597Chris Craik } 885faa79ff9d964de940660d2226d5b06ded9294597Chris Craik 886faa79ff9d964de940660d2226d5b06ded9294597Chris Craik Rect clipBounds; 887faa79ff9d964de940660d2226d5b06ded9294597Chris Craik properties().getClippingRectForFlags(CLIP_TO_CLIP_BOUNDS, &clipBounds); 888faa79ff9d964de940660d2226d5b06ded9294597Chris Craik SkPath clipBoundsPath; 889faa79ff9d964de940660d2226d5b06ded9294597Chris Craik clipBoundsPath.addRect(clipBounds.left, clipBounds.top, 890faa79ff9d964de940660d2226d5b06ded9294597Chris Craik clipBounds.right, clipBounds.bottom); 8917466986d2055eb8711f36a85ac539b1572ffe805Chris Craik 89202a26300fb129608eb1df8cf31c14a5a5d8bd6edTom Hudson Op(*outlinePath, clipBoundsPath, kIntersect_SkPathOp, frameAllocatedPath); 8937466986d2055eb8711f36a85ac539b1572ffe805Chris Craik outlinePath = frameAllocatedPath; 8947466986d2055eb8711f36a85ac539b1572ffe805Chris Craik } 8957466986d2055eb8711f36a85ac539b1572ffe805Chris Craik 896b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik DisplayListOp* shadowOp = new (handler.allocator()) DrawShadowOp( 8977466986d2055eb8711f36a85ac539b1572ffe805Chris Craik shadowMatrixXY, shadowMatrixZ, casterAlpha, outlinePath); 898b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik handler(shadowOp, PROPERTY_SAVECOUNT, properties().getClipToBounds()); 899b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik} 900b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik 901113e0824d6bddf4376240681f9cf6a2deded9498John Reck#define SHADOW_DELTA 0.1f 902113e0824d6bddf4376240681f9cf6a2deded9498John Reck 903113e0824d6bddf4376240681f9cf6a2deded9498John Recktemplate <class T> 904c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craikvoid RenderNode::issueOperationsOf3dChildren(ChildrenSelectMode mode, 905272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck const Matrix4& initialTransform, const std::vector<ZDrawRenderNodeOpPair>& zTranslatedNodes, 906c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik OpenGLRenderer& renderer, T& handler) { 907113e0824d6bddf4376240681f9cf6a2deded9498John Reck const int size = zTranslatedNodes.size(); 908113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (size == 0 909b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik || (mode == ChildrenSelectMode::NegativeZChildren && zTranslatedNodes[0].key > 0.0f) 910b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik || (mode == ChildrenSelectMode::PositiveZChildren && zTranslatedNodes[size - 1].key < 0.0f)) { 911113e0824d6bddf4376240681f9cf6a2deded9498John Reck // no 3d children to draw 912113e0824d6bddf4376240681f9cf6a2deded9498John Reck return; 913113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 914113e0824d6bddf4376240681f9cf6a2deded9498John Reck 915c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik // Apply the base transform of the parent of the 3d children. This isolates 916c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik // 3d children of the current chunk from transformations made in previous chunks. 917eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita int rootRestoreTo = renderer.save(SaveFlags::Matrix); 9186daa13c5fa7577fa1d8371deca446f6ca911f38fChris Craik renderer.setGlobalMatrix(initialTransform); 919c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik 920113e0824d6bddf4376240681f9cf6a2deded9498John Reck /** 921113e0824d6bddf4376240681f9cf6a2deded9498John Reck * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters 922113e0824d6bddf4376240681f9cf6a2deded9498John Reck * with very similar Z heights to draw together. 923113e0824d6bddf4376240681f9cf6a2deded9498John Reck * 924113e0824d6bddf4376240681f9cf6a2deded9498John Reck * This way, if Views A & B have the same Z height and are both casting shadows, the shadows are 925113e0824d6bddf4376240681f9cf6a2deded9498John Reck * underneath both, and neither's shadow is drawn on top of the other. 926113e0824d6bddf4376240681f9cf6a2deded9498John Reck */ 927113e0824d6bddf4376240681f9cf6a2deded9498John Reck const size_t nonNegativeIndex = findNonNegativeIndex(zTranslatedNodes); 928113e0824d6bddf4376240681f9cf6a2deded9498John Reck size_t drawIndex, shadowIndex, endIndex; 929b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik if (mode == ChildrenSelectMode::NegativeZChildren) { 930113e0824d6bddf4376240681f9cf6a2deded9498John Reck drawIndex = 0; 931113e0824d6bddf4376240681f9cf6a2deded9498John Reck endIndex = nonNegativeIndex; 932113e0824d6bddf4376240681f9cf6a2deded9498John Reck shadowIndex = endIndex; // draw no shadows 933113e0824d6bddf4376240681f9cf6a2deded9498John Reck } else { 934113e0824d6bddf4376240681f9cf6a2deded9498John Reck drawIndex = nonNegativeIndex; 935113e0824d6bddf4376240681f9cf6a2deded9498John Reck endIndex = size; 936113e0824d6bddf4376240681f9cf6a2deded9498John Reck shadowIndex = drawIndex; // potentially draw shadow for each pos Z child 937113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 9383f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 9393f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik DISPLAY_LIST_LOGD("%*s%d %s 3d children:", (handler.level() + 1) * 2, "", 9403f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik endIndex - drawIndex, mode == kNegativeZChildren ? "negative" : "positive"); 9413f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 942113e0824d6bddf4376240681f9cf6a2deded9498John Reck float lastCasterZ = 0.0f; 943113e0824d6bddf4376240681f9cf6a2deded9498John Reck while (shadowIndex < endIndex || drawIndex < endIndex) { 944113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (shadowIndex < endIndex) { 945a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik DrawRenderNodeOp* casterOp = zTranslatedNodes[shadowIndex].value; 946b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik RenderNode* caster = casterOp->renderNode; 947113e0824d6bddf4376240681f9cf6a2deded9498John Reck const float casterZ = zTranslatedNodes[shadowIndex].key; 948113e0824d6bddf4376240681f9cf6a2deded9498John Reck // attempt to render the shadow if the caster about to be drawn is its caster, 949113e0824d6bddf4376240681f9cf6a2deded9498John Reck // OR if its caster's Z value is similar to the previous potential caster 950113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (shadowIndex == drawIndex || casterZ - lastCasterZ < SHADOW_DELTA) { 9518d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik caster->issueDrawShadowOperation(casterOp->localMatrix, handler); 952113e0824d6bddf4376240681f9cf6a2deded9498John Reck 953113e0824d6bddf4376240681f9cf6a2deded9498John Reck lastCasterZ = casterZ; // must do this even if current caster not casting a shadow 954113e0824d6bddf4376240681f9cf6a2deded9498John Reck shadowIndex++; 955113e0824d6bddf4376240681f9cf6a2deded9498John Reck continue; 956113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 957113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 958113e0824d6bddf4376240681f9cf6a2deded9498John Reck 959113e0824d6bddf4376240681f9cf6a2deded9498John Reck // only the actual child DL draw needs to be in save/restore, 960113e0824d6bddf4376240681f9cf6a2deded9498John Reck // since it modifies the renderer's matrix 961eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita int restoreTo = renderer.save(SaveFlags::Matrix); 962113e0824d6bddf4376240681f9cf6a2deded9498John Reck 963a7090e0cfd7c719a6d4c03aae34f5db98754cbddChris Craik DrawRenderNodeOp* childOp = zTranslatedNodes[drawIndex].value; 964113e0824d6bddf4376240681f9cf6a2deded9498John Reck 9658d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik renderer.concatMatrix(childOp->localMatrix); 9668d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik childOp->skipInOrderDraw = false; // this is horrible, I'm so sorry everyone 967d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck handler(childOp, renderer.getSaveCount() - 1, properties().getClipToBounds()); 9688d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik childOp->skipInOrderDraw = true; 969113e0824d6bddf4376240681f9cf6a2deded9498John Reck 970113e0824d6bddf4376240681f9cf6a2deded9498John Reck renderer.restoreToCount(restoreTo); 971113e0824d6bddf4376240681f9cf6a2deded9498John Reck drawIndex++; 972113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 973c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik renderer.restoreToCount(rootRestoreTo); 974113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 975113e0824d6bddf4376240681f9cf6a2deded9498John Reck 976113e0824d6bddf4376240681f9cf6a2deded9498John Recktemplate <class T> 977b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craikvoid RenderNode::issueOperationsOfProjectedChildren(OpenGLRenderer& renderer, T& handler) { 9783f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik DISPLAY_LIST_LOGD("%*s%d projected children:", (handler.level() + 1) * 2, "", mProjectedNodes.size()); 9793f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik const SkPath* projectionReceiverOutline = properties().getOutline().getPath(); 9803f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik int restoreTo = renderer.getSaveCount(); 9813f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 982b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik LinearAllocator& alloc = handler.allocator(); 983eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita handler(new (alloc) SaveOp(SaveFlags::MatrixClip), 984b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik PROPERTY_SAVECOUNT, properties().getClipToBounds()); 985b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik 986b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik // Transform renderer to match background we're projecting onto 987b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik // (by offsetting canvas by translationX/Y of background rendernode, since only those are set) 988b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik const DisplayListOp* op = 98910ed692118552a01ff97b095295852b631e51beeChris Craik#if HWUI_NEW_OPS 99010ed692118552a01ff97b095295852b631e51beeChris Craik nullptr; 99110ed692118552a01ff97b095295852b631e51beeChris Craik LOG_ALWAYS_FATAL("unsupported"); 99210ed692118552a01ff97b095295852b631e51beeChris Craik#else 993003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik (mDisplayList->getOps()[mDisplayList->projectionReceiveIndex]); 99410ed692118552a01ff97b095295852b631e51beeChris Craik#endif 995b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik const DrawRenderNodeOp* backgroundOp = reinterpret_cast<const DrawRenderNodeOp*>(op); 996b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik const RenderProperties& backgroundProps = backgroundOp->renderNode->properties(); 997b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik renderer.translate(backgroundProps.getTranslationX(), backgroundProps.getTranslationY()); 998b3cca876c2e11b865cb4f83abe2c48a60b95af5bChris Craik 9996fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik // If the projection receiver has an outline, we mask projected content to it 1000fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik // (which we know, apriori, are all tessellated paths) 1001fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik renderer.setProjectionPathMask(alloc, projectionReceiverOutline); 10023f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 10033f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik // draw projected nodes 1004113e0824d6bddf4376240681f9cf6a2deded9498John Reck for (size_t i = 0; i < mProjectedNodes.size(); i++) { 10058d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik renderNodeOp_t* childOp = mProjectedNodes[i]; 1006113e0824d6bddf4376240681f9cf6a2deded9498John Reck 1007113e0824d6bddf4376240681f9cf6a2deded9498John Reck // matrix save, concat, and restore can be done safely without allocating operations 1008eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita int restoreTo = renderer.save(SaveFlags::Matrix); 10098d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik renderer.concatMatrix(childOp->transformFromCompositingAncestor); 10108d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik childOp->skipInOrderDraw = false; // this is horrible, I'm so sorry everyone 1011d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck handler(childOp, renderer.getSaveCount() - 1, properties().getClipToBounds()); 10128d1f2120fe80b23ab03c7168e3b6b2d13bafe2e7Chris Craik childOp->skipInOrderDraw = true; 1013113e0824d6bddf4376240681f9cf6a2deded9498John Reck renderer.restoreToCount(restoreTo); 1014113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 10153f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik 1016fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik handler(new (alloc) RestoreToCountOp(restoreTo), 1017fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik PROPERTY_SAVECOUNT, properties().getClipToBounds()); 1018113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 1019113e0824d6bddf4376240681f9cf6a2deded9498John Reck 1020113e0824d6bddf4376240681f9cf6a2deded9498John Reck/** 1021113e0824d6bddf4376240681f9cf6a2deded9498John Reck * This function serves both defer and replay modes, and will organize the displayList's component 1022113e0824d6bddf4376240681f9cf6a2deded9498John Reck * operations for a single frame: 1023113e0824d6bddf4376240681f9cf6a2deded9498John Reck * 1024113e0824d6bddf4376240681f9cf6a2deded9498John Reck * Every 'simple' state operation that affects just the matrix and alpha (or other factors of 1025113e0824d6bddf4376240681f9cf6a2deded9498John Reck * DeferredDisplayState) may be issued directly to the renderer, but complex operations (with custom 1026113e0824d6bddf4376240681f9cf6a2deded9498John Reck * defer logic) and operations in displayListOps are issued through the 'handler' which handles the 1027113e0824d6bddf4376240681f9cf6a2deded9498John Reck * defer vs replay logic, per operation 1028113e0824d6bddf4376240681f9cf6a2deded9498John Reck */ 1029113e0824d6bddf4376240681f9cf6a2deded9498John Recktemplate <class T> 1030b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craikvoid RenderNode::issueOperations(OpenGLRenderer& renderer, T& handler) { 1031003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik if (mDisplayList->isEmpty()) { 1032bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", handler.level() * 2, "", 1033bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik this, getName()); 10340645128b80621edee70f8cab4afb208fe0c26becChris Craik return; 10350645128b80621edee70f8cab4afb208fe0c26becChris Craik } 10360645128b80621edee70f8cab4afb208fe0c26becChris Craik 10370b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#if HWUI_NEW_OPS 10380b7e8245db728d127ada698be63d78b33fc6e4daChris Craik const bool drawLayer = false; 10390b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#else 104051d6a3db97bdd5315f1a17a4b447d10a92217b98Chris Craik const bool drawLayer = (mLayer && (&renderer != mLayer->renderer.get())); 10410b7e8245db728d127ada698be63d78b33fc6e4daChris Craik#endif 104225fbb3fa1138675379102a44405852555cefccbdJohn Reck // If we are updating the contents of mLayer, we don't want to apply any of 104325fbb3fa1138675379102a44405852555cefccbdJohn Reck // the RenderNode's properties to this issueOperations pass. Those will all 104425fbb3fa1138675379102a44405852555cefccbdJohn Reck // be applied when the layer is drawn, aka when this is true. 104525fbb3fa1138675379102a44405852555cefccbdJohn Reck const bool useViewProperties = (!mLayer || drawLayer); 10460645128b80621edee70f8cab4afb208fe0c26becChris Craik if (useViewProperties) { 10470645128b80621edee70f8cab4afb208fe0c26becChris Craik const Outline& outline = properties().getOutline(); 10488d0ec389531d071529fb0a800f10733b057205d9Teng-Hui Zhu if (properties().getAlpha() <= 0 10498d0ec389531d071529fb0a800f10733b057205d9Teng-Hui Zhu || (outline.getShouldClip() && outline.isEmpty()) 10508d0ec389531d071529fb0a800f10733b057205d9Teng-Hui Zhu || properties().getScaleX() == 0 10518d0ec389531d071529fb0a800f10733b057205d9Teng-Hui Zhu || properties().getScaleY() == 0) { 1052bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik DISPLAY_LIST_LOGD("%*sRejected display list (%p, %s)", handler.level() * 2, "", 1053bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik this, getName()); 10540645128b80621edee70f8cab4afb208fe0c26becChris Craik return; 10550645128b80621edee70f8cab4afb208fe0c26becChris Craik } 1056113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 1057113e0824d6bddf4376240681f9cf6a2deded9498John Reck 10583f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik handler.startMark(getName()); 1059b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik 1060113e0824d6bddf4376240681f9cf6a2deded9498John Reck#if DEBUG_DISPLAY_LIST 10613f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik const Rect& clipRect = renderer.getLocalClipBounds(); 10623f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), localClipBounds: %.0f, %.0f, %.0f, %.0f", 1063031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik handler.level() * 2, "", this, getName(), 10643f085429fd47ebd32ac2463b3eae2a5a6c17be25Chris Craik clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); 1065113e0824d6bddf4376240681f9cf6a2deded9498John Reck#endif 1066113e0824d6bddf4376240681f9cf6a2deded9498John Reck 1067113e0824d6bddf4376240681f9cf6a2deded9498John Reck LinearAllocator& alloc = handler.allocator(); 1068113e0824d6bddf4376240681f9cf6a2deded9498John Reck int restoreTo = renderer.getSaveCount(); 1069eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita handler(new (alloc) SaveOp(SaveFlags::MatrixClip), 1070d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck PROPERTY_SAVECOUNT, properties().getClipToBounds()); 1071113e0824d6bddf4376240681f9cf6a2deded9498John Reck 1072bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik DISPLAY_LIST_LOGD("%*sSave %d %d", (handler.level() + 1) * 2, "", 1073eecff56fed5dd5206acfbc5007b4912081b36d3bFlorin Malita SaveFlags::MatrixClip, restoreTo); 1074113e0824d6bddf4376240681f9cf6a2deded9498John Reck 107525fbb3fa1138675379102a44405852555cefccbdJohn Reck if (useViewProperties) { 107625fbb3fa1138675379102a44405852555cefccbdJohn Reck setViewProperties<T>(renderer, handler); 107725fbb3fa1138675379102a44405852555cefccbdJohn Reck } 1078113e0824d6bddf4376240681f9cf6a2deded9498John Reck 107910ed692118552a01ff97b095295852b631e51beeChris Craik#if HWUI_NEW_OPS 108010ed692118552a01ff97b095295852b631e51beeChris Craik LOG_ALWAYS_FATAL("legacy op traversal not supported"); 108110ed692118552a01ff97b095295852b631e51beeChris Craik#else 10828c271ca63b62061fd22cfee78fd6a574b44476fdChris Craik bool quickRejected = properties().getClipToBounds() 10838c271ca63b62061fd22cfee78fd6a574b44476fdChris Craik && renderer.quickRejectConservative(0, 0, properties().getWidth(), properties().getHeight()); 1084113e0824d6bddf4376240681f9cf6a2deded9498John Reck if (!quickRejected) { 1085c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik Matrix4 initialTransform(*(renderer.currentTransform())); 1086ac7b6d33d23cb0baaf61c723346198d41f012035Tom Hudson renderer.setBaseTransform(initialTransform); 1087c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik 108825fbb3fa1138675379102a44405852555cefccbdJohn Reck if (drawLayer) { 10893aadd60521960be063ee06208562ccb63dc414e3Chris Craik handler(new (alloc) DrawLayerOp(mLayer), 109025fbb3fa1138675379102a44405852555cefccbdJohn Reck renderer.getSaveCount() - 1, properties().getClipToBounds()); 109125fbb3fa1138675379102a44405852555cefccbdJohn Reck } else { 1092c166b6c4fc3e1158ca08cfed24639409161055cfChris Craik const int saveCountOffset = renderer.getSaveCount() - 1; 1093003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik const int projectionReceiveIndex = mDisplayList->projectionReceiveIndex; 1094003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik for (size_t chunkIndex = 0; chunkIndex < mDisplayList->getChunks().size(); chunkIndex++) { 1095003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik const DisplayList::Chunk& chunk = mDisplayList->getChunks()[chunkIndex]; 109625fbb3fa1138675379102a44405852555cefccbdJohn Reck 1097272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck std::vector<ZDrawRenderNodeOpPair> zTranslatedNodes; 10988afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik buildZSortedChildList(chunk, zTranslatedNodes); 109925fbb3fa1138675379102a44405852555cefccbdJohn Reck 1100b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik issueOperationsOf3dChildren(ChildrenSelectMode::NegativeZChildren, 1101c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik initialTransform, zTranslatedNodes, renderer, handler); 1102c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik 1103edaecc1db0584fa017822dfc2da0c968b53967e6Andreas Gampe for (size_t opIndex = chunk.beginOpIndex; opIndex < chunk.endOpIndex; opIndex++) { 1104003cc3dec8e2a92e51086fbcd5ee1bb236efa701Chris Craik DisplayListOp *op = mDisplayList->getOps()[opIndex]; 110580d4902196899d1325cd9f52c06ae0174cf9bd4cChris Craik#if DEBUG_DISPLAY_LIST 1106031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik op->output(handler.level() + 1); 110780d4902196899d1325cd9f52c06ae0174cf9bd4cChris Craik#endif 11088afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik handler(op, saveCountOffset, properties().getClipToBounds()); 110925fbb3fa1138675379102a44405852555cefccbdJohn Reck 1110272a685f17cc4828257e521a6f62b7b17870f75eJohn Reck if (CC_UNLIKELY(!mProjectedNodes.empty() && projectionReceiveIndex >= 0 && 1111edaecc1db0584fa017822dfc2da0c968b53967e6Andreas Gampe opIndex == static_cast<size_t>(projectionReceiveIndex))) { 11128afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik issueOperationsOfProjectedChildren(renderer, handler); 11138afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik } 111425fbb3fa1138675379102a44405852555cefccbdJohn Reck } 1115113e0824d6bddf4376240681f9cf6a2deded9498John Reck 1116b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik issueOperationsOf3dChildren(ChildrenSelectMode::PositiveZChildren, 1117c3e75f9d54b3629b3fd27afafa2e07bd07dad9b3Chris Craik initialTransform, zTranslatedNodes, renderer, handler); 11188afd0f245cc0c4a0366f39f41b5f78e47ee83be3Chris Craik } 111925fbb3fa1138675379102a44405852555cefccbdJohn Reck } 1120113e0824d6bddf4376240681f9cf6a2deded9498John Reck } 112110ed692118552a01ff97b095295852b631e51beeChris Craik#endif 1122113e0824d6bddf4376240681f9cf6a2deded9498John Reck 1123bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (handler.level() + 1) * 2, "", restoreTo); 1124113e0824d6bddf4376240681f9cf6a2deded9498John Reck handler(new (alloc) RestoreToCountOp(restoreTo), 1125d0a0b2a3140bfb1819a116413ce9d81886697a07John Reck PROPERTY_SAVECOUNT, properties().getClipToBounds()); 1126b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik 1127bf72eb80d9e00fe2fa360dff0ef581ea27c8e965Chris Craik DISPLAY_LIST_LOGD("%*sDone (%p, %s)", handler.level() * 2, "", this, getName()); 1128b265e2ca50b6ceb2fd2987ef1f7d063b1bde19aeChris Craik handler.endMark(); 1129113e0824d6bddf4376240681f9cf6a2deded9498John Reck} 1130113e0824d6bddf4376240681f9cf6a2deded9498John Reck 1131113e0824d6bddf4376240681f9cf6a2deded9498John Reck} /* namespace uirenderer */ 1132113e0824d6bddf4376240681f9cf6a2deded9498John Reck} /* namespace android */ 1133