1*d57664e9SAndroid Build Coastguard Worker /* 2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker * 4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*d57664e9SAndroid Build Coastguard Worker * 8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*d57664e9SAndroid Build Coastguard Worker * 10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*d57664e9SAndroid Build Coastguard Worker * limitations under the License. 15*d57664e9SAndroid Build Coastguard Worker */ 16*d57664e9SAndroid Build Coastguard Worker 17*d57664e9SAndroid Build Coastguard Worker #pragma once 18*d57664e9SAndroid Build Coastguard Worker 19*d57664e9SAndroid Build Coastguard Worker #include <SkMatrix.h> 20*d57664e9SAndroid Build Coastguard Worker 21*d57664e9SAndroid Build Coastguard Worker #include <utils/LinearAllocator.h> 22*d57664e9SAndroid Build Coastguard Worker #include <utils/RefBase.h> 23*d57664e9SAndroid Build Coastguard Worker #include <utils/String8.h> 24*d57664e9SAndroid Build Coastguard Worker 25*d57664e9SAndroid Build Coastguard Worker #include <cutils/compiler.h> 26*d57664e9SAndroid Build Coastguard Worker 27*d57664e9SAndroid Build Coastguard Worker #include <androidfw/ResourceTypes.h> 28*d57664e9SAndroid Build Coastguard Worker 29*d57664e9SAndroid Build Coastguard Worker #include <ui/FatVector.h> 30*d57664e9SAndroid Build Coastguard Worker 31*d57664e9SAndroid Build Coastguard Worker #include "AnimatorManager.h" 32*d57664e9SAndroid Build Coastguard Worker #include "CanvasTransform.h" 33*d57664e9SAndroid Build Coastguard Worker #include "Debug.h" 34*d57664e9SAndroid Build Coastguard Worker #include "DisplayList.h" 35*d57664e9SAndroid Build Coastguard Worker #include "Matrix.h" 36*d57664e9SAndroid Build Coastguard Worker #include "RenderProperties.h" 37*d57664e9SAndroid Build Coastguard Worker #include "pipeline/skia/HolePunch.h" 38*d57664e9SAndroid Build Coastguard Worker #include "pipeline/skia/SkiaDisplayList.h" 39*d57664e9SAndroid Build Coastguard Worker #include "pipeline/skia/SkiaLayer.h" 40*d57664e9SAndroid Build Coastguard Worker 41*d57664e9SAndroid Build Coastguard Worker #include <vector> 42*d57664e9SAndroid Build Coastguard Worker #include <pipeline/skia/StretchMask.h> 43*d57664e9SAndroid Build Coastguard Worker 44*d57664e9SAndroid Build Coastguard Worker class SkBitmap; 45*d57664e9SAndroid Build Coastguard Worker class SkPaint; 46*d57664e9SAndroid Build Coastguard Worker class SkPath; 47*d57664e9SAndroid Build Coastguard Worker class SkRegion; 48*d57664e9SAndroid Build Coastguard Worker class SkSurface; 49*d57664e9SAndroid Build Coastguard Worker 50*d57664e9SAndroid Build Coastguard Worker namespace android { 51*d57664e9SAndroid Build Coastguard Worker namespace uirenderer { 52*d57664e9SAndroid Build Coastguard Worker 53*d57664e9SAndroid Build Coastguard Worker class CanvasState; 54*d57664e9SAndroid Build Coastguard Worker class Rect; 55*d57664e9SAndroid Build Coastguard Worker class SkiaShader; 56*d57664e9SAndroid Build Coastguard Worker struct RenderNodeOp; 57*d57664e9SAndroid Build Coastguard Worker 58*d57664e9SAndroid Build Coastguard Worker class TreeInfo; 59*d57664e9SAndroid Build Coastguard Worker class TreeObserver; 60*d57664e9SAndroid Build Coastguard Worker 61*d57664e9SAndroid Build Coastguard Worker namespace proto { 62*d57664e9SAndroid Build Coastguard Worker class RenderNode; 63*d57664e9SAndroid Build Coastguard Worker } 64*d57664e9SAndroid Build Coastguard Worker 65*d57664e9SAndroid Build Coastguard Worker /** 66*d57664e9SAndroid Build Coastguard Worker * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display 67*d57664e9SAndroid Build Coastguard Worker * properties. 68*d57664e9SAndroid Build Coastguard Worker * 69*d57664e9SAndroid Build Coastguard Worker * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording 70*d57664e9SAndroid Build Coastguard Worker * functionality is split between RecordingCanvas (which manages the recording), DisplayList 71*d57664e9SAndroid Build Coastguard Worker * (which holds the actual data), and RenderNode (which holds properties used for render playback). 72*d57664e9SAndroid Build Coastguard Worker * 73*d57664e9SAndroid Build Coastguard Worker * Note that DisplayList is swapped out from beneath an individual RenderNode when a view's 74*d57664e9SAndroid Build Coastguard Worker * recorded stream of canvas operations is refreshed. The RenderNode (and its properties) stay 75*d57664e9SAndroid Build Coastguard Worker * attached. 76*d57664e9SAndroid Build Coastguard Worker */ 77*d57664e9SAndroid Build Coastguard Worker class RenderNode : public VirtualLightRefBase { 78*d57664e9SAndroid Build Coastguard Worker friend class TestUtils; // allow TestUtils to access syncDisplayList / syncProperties 79*d57664e9SAndroid Build Coastguard Worker 80*d57664e9SAndroid Build Coastguard Worker public: 81*d57664e9SAndroid Build Coastguard Worker enum DirtyPropertyMask { 82*d57664e9SAndroid Build Coastguard Worker GENERIC = 1 << 1, 83*d57664e9SAndroid Build Coastguard Worker TRANSLATION_X = 1 << 2, 84*d57664e9SAndroid Build Coastguard Worker TRANSLATION_Y = 1 << 3, 85*d57664e9SAndroid Build Coastguard Worker TRANSLATION_Z = 1 << 4, 86*d57664e9SAndroid Build Coastguard Worker SCALE_X = 1 << 5, 87*d57664e9SAndroid Build Coastguard Worker SCALE_Y = 1 << 6, 88*d57664e9SAndroid Build Coastguard Worker ROTATION = 1 << 7, 89*d57664e9SAndroid Build Coastguard Worker ROTATION_X = 1 << 8, 90*d57664e9SAndroid Build Coastguard Worker ROTATION_Y = 1 << 9, 91*d57664e9SAndroid Build Coastguard Worker X = 1 << 10, 92*d57664e9SAndroid Build Coastguard Worker Y = 1 << 11, 93*d57664e9SAndroid Build Coastguard Worker Z = 1 << 12, 94*d57664e9SAndroid Build Coastguard Worker ALPHA = 1 << 13, 95*d57664e9SAndroid Build Coastguard Worker DISPLAY_LIST = 1 << 14, 96*d57664e9SAndroid Build Coastguard Worker }; 97*d57664e9SAndroid Build Coastguard Worker 98*d57664e9SAndroid Build Coastguard Worker RenderNode(); 99*d57664e9SAndroid Build Coastguard Worker virtual ~RenderNode(); 100*d57664e9SAndroid Build Coastguard Worker 101*d57664e9SAndroid Build Coastguard Worker // See flags defined in DisplayList.java 102*d57664e9SAndroid Build Coastguard Worker enum ReplayFlag { kReplayFlag_ClipChildren = 0x1 }; 103*d57664e9SAndroid Build Coastguard Worker 104*d57664e9SAndroid Build Coastguard Worker void setStagingDisplayList(DisplayList&& newData); 105*d57664e9SAndroid Build Coastguard Worker void discardStagingDisplayList(); 106*d57664e9SAndroid Build Coastguard Worker 107*d57664e9SAndroid Build Coastguard Worker void output(); 108*d57664e9SAndroid Build Coastguard Worker int getUsageSize(); 109*d57664e9SAndroid Build Coastguard Worker int getAllocatedSize(); 110*d57664e9SAndroid Build Coastguard Worker isRenderable()111*d57664e9SAndroid Build Coastguard Worker bool isRenderable() const { return mDisplayList.hasContent(); } 112*d57664e9SAndroid Build Coastguard Worker hasProjectionReceiver()113*d57664e9SAndroid Build Coastguard Worker bool hasProjectionReceiver() const { 114*d57664e9SAndroid Build Coastguard Worker return mDisplayList.containsProjectionReceiver(); 115*d57664e9SAndroid Build Coastguard Worker } 116*d57664e9SAndroid Build Coastguard Worker getName()117*d57664e9SAndroid Build Coastguard Worker const char* getName() const { return mName.c_str(); } 118*d57664e9SAndroid Build Coastguard Worker setName(const char * name)119*d57664e9SAndroid Build Coastguard Worker void setName(const char* name) { 120*d57664e9SAndroid Build Coastguard Worker if (name) { 121*d57664e9SAndroid Build Coastguard Worker const char* lastPeriod = strrchr(name, '.'); 122*d57664e9SAndroid Build Coastguard Worker if (lastPeriod) { 123*d57664e9SAndroid Build Coastguard Worker mName = (lastPeriod + 1); 124*d57664e9SAndroid Build Coastguard Worker } else { 125*d57664e9SAndroid Build Coastguard Worker mName = name; 126*d57664e9SAndroid Build Coastguard Worker } 127*d57664e9SAndroid Build Coastguard Worker } 128*d57664e9SAndroid Build Coastguard Worker } 129*d57664e9SAndroid Build Coastguard Worker getStretchMask()130*d57664e9SAndroid Build Coastguard Worker StretchMask& getStretchMask() { return mStretchMask; } 131*d57664e9SAndroid Build Coastguard Worker isPropertyFieldDirty(DirtyPropertyMask field)132*d57664e9SAndroid Build Coastguard Worker bool isPropertyFieldDirty(DirtyPropertyMask field) const { 133*d57664e9SAndroid Build Coastguard Worker return mDirtyPropertyFields & field; 134*d57664e9SAndroid Build Coastguard Worker } 135*d57664e9SAndroid Build Coastguard Worker setPropertyFieldsDirty(uint32_t fields)136*d57664e9SAndroid Build Coastguard Worker void setPropertyFieldsDirty(uint32_t fields) { mDirtyPropertyFields |= fields; } 137*d57664e9SAndroid Build Coastguard Worker properties()138*d57664e9SAndroid Build Coastguard Worker const RenderProperties& properties() const { return mProperties; } 139*d57664e9SAndroid Build Coastguard Worker animatorProperties()140*d57664e9SAndroid Build Coastguard Worker RenderProperties& animatorProperties() { return mProperties; } 141*d57664e9SAndroid Build Coastguard Worker stagingProperties()142*d57664e9SAndroid Build Coastguard Worker const RenderProperties& stagingProperties() { return mStagingProperties; } 143*d57664e9SAndroid Build Coastguard Worker mutateStagingProperties()144*d57664e9SAndroid Build Coastguard Worker RenderProperties& mutateStagingProperties() { return mStagingProperties; } 145*d57664e9SAndroid Build Coastguard Worker isValid()146*d57664e9SAndroid Build Coastguard Worker bool isValid() { return mValid; } 147*d57664e9SAndroid Build Coastguard Worker getWidth()148*d57664e9SAndroid Build Coastguard Worker int getWidth() const { return properties().getWidth(); } 149*d57664e9SAndroid Build Coastguard Worker getHeight()150*d57664e9SAndroid Build Coastguard Worker int getHeight() const { return properties().getHeight(); } 151*d57664e9SAndroid Build Coastguard Worker 152*d57664e9SAndroid Build Coastguard Worker virtual void prepareTree(TreeInfo& info); 153*d57664e9SAndroid Build Coastguard Worker void destroyHardwareResources(TreeInfo* info = nullptr); 154*d57664e9SAndroid Build Coastguard Worker void destroyLayers(); 155*d57664e9SAndroid Build Coastguard Worker 156*d57664e9SAndroid Build Coastguard Worker // UI thread only! 157*d57664e9SAndroid Build Coastguard Worker void addAnimator(const sp<BaseRenderNodeAnimator>& animator); 158*d57664e9SAndroid Build Coastguard Worker void removeAnimator(const sp<BaseRenderNodeAnimator>& animator); 159*d57664e9SAndroid Build Coastguard Worker 160*d57664e9SAndroid Build Coastguard Worker // This can only happen during pushStaging() onAnimatorTargetChanged(BaseRenderNodeAnimator * animator)161*d57664e9SAndroid Build Coastguard Worker void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) { 162*d57664e9SAndroid Build Coastguard Worker mAnimatorManager.onAnimatorTargetChanged(animator); 163*d57664e9SAndroid Build Coastguard Worker } 164*d57664e9SAndroid Build Coastguard Worker animators()165*d57664e9SAndroid Build Coastguard Worker AnimatorManager& animators() { return mAnimatorManager; } 166*d57664e9SAndroid Build Coastguard Worker 167*d57664e9SAndroid Build Coastguard Worker void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false) const; 168*d57664e9SAndroid Build Coastguard Worker nothingToDraw()169*d57664e9SAndroid Build Coastguard Worker bool nothingToDraw() const { 170*d57664e9SAndroid Build Coastguard Worker const Outline& outline = properties().getOutline(); 171*d57664e9SAndroid Build Coastguard Worker return !mDisplayList.isValid() || properties().getAlpha() <= 0 || 172*d57664e9SAndroid Build Coastguard Worker (outline.getShouldClip() && outline.isEmpty()) || properties().getScaleX() == 0 || 173*d57664e9SAndroid Build Coastguard Worker properties().getScaleY() == 0; 174*d57664e9SAndroid Build Coastguard Worker } 175*d57664e9SAndroid Build Coastguard Worker getDisplayList()176*d57664e9SAndroid Build Coastguard Worker const DisplayList& getDisplayList() const { return mDisplayList; } 177*d57664e9SAndroid Build Coastguard Worker // TODO: can this be cleaned up? getDisplayList()178*d57664e9SAndroid Build Coastguard Worker DisplayList& getDisplayList() { return mDisplayList; } 179*d57664e9SAndroid Build Coastguard Worker 180*d57664e9SAndroid Build Coastguard Worker // Note: The position callbacks are relying on the listener using 181*d57664e9SAndroid Build Coastguard Worker // the frameNumber to appropriately batch/synchronize these transactions. 182*d57664e9SAndroid Build Coastguard Worker // There is no other filtering/batching to ensure that only the "final" 183*d57664e9SAndroid Build Coastguard Worker // state called once per frame. 184*d57664e9SAndroid Build Coastguard Worker class PositionListener : public VirtualLightRefBase { 185*d57664e9SAndroid Build Coastguard Worker public: ~PositionListener()186*d57664e9SAndroid Build Coastguard Worker virtual ~PositionListener() {} 187*d57664e9SAndroid Build Coastguard Worker // Called when the RenderNode's position changes 188*d57664e9SAndroid Build Coastguard Worker virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) = 0; 189*d57664e9SAndroid Build Coastguard Worker // Called when the RenderNode no longer has a position. As in, it's 190*d57664e9SAndroid Build Coastguard Worker // no longer being drawn. 191*d57664e9SAndroid Build Coastguard Worker // Note, tree info might be null 192*d57664e9SAndroid Build Coastguard Worker virtual void onPositionLost(RenderNode& node, const TreeInfo* info) = 0; 193*d57664e9SAndroid Build Coastguard Worker }; 194*d57664e9SAndroid Build Coastguard Worker setPositionListener(PositionListener * listener)195*d57664e9SAndroid Build Coastguard Worker void setPositionListener(PositionListener* listener) { 196*d57664e9SAndroid Build Coastguard Worker mStagingPositionListener = listener; 197*d57664e9SAndroid Build Coastguard Worker mPositionListenerDirty = true; 198*d57664e9SAndroid Build Coastguard Worker } 199*d57664e9SAndroid Build Coastguard Worker 200*d57664e9SAndroid Build Coastguard Worker // This is only modified in MODE_FULL, so it can be safely accessed 201*d57664e9SAndroid Build Coastguard Worker // on the UI thread. hasParents()202*d57664e9SAndroid Build Coastguard Worker bool hasParents() { return mParentCount; } 203*d57664e9SAndroid Build Coastguard Worker 204*d57664e9SAndroid Build Coastguard Worker void onRemovedFromTree(TreeInfo* info); 205*d57664e9SAndroid Build Coastguard Worker 206*d57664e9SAndroid Build Coastguard Worker // Called by CanvasContext to promote a RenderNode to be a root node makeRoot()207*d57664e9SAndroid Build Coastguard Worker void makeRoot() { incParentRefCount(); } 208*d57664e9SAndroid Build Coastguard Worker 209*d57664e9SAndroid Build Coastguard Worker // Called by CanvasContext when it drops a RenderNode from being a root node 210*d57664e9SAndroid Build Coastguard Worker void clearRoot(); 211*d57664e9SAndroid Build Coastguard Worker 212*d57664e9SAndroid Build Coastguard Worker void output(std::ostream& output, uint32_t level); 213*d57664e9SAndroid Build Coastguard Worker 214*d57664e9SAndroid Build Coastguard Worker void visit(std::function<void(const RenderNode&)>) const; 215*d57664e9SAndroid Build Coastguard Worker setUsageHint(UsageHint usageHint)216*d57664e9SAndroid Build Coastguard Worker void setUsageHint(UsageHint usageHint) { mUsageHint = usageHint; } 217*d57664e9SAndroid Build Coastguard Worker usageHint()218*d57664e9SAndroid Build Coastguard Worker UsageHint usageHint() const { return mUsageHint; } 219*d57664e9SAndroid Build Coastguard Worker uniqueId()220*d57664e9SAndroid Build Coastguard Worker int64_t uniqueId() const { return mUniqueId; } 221*d57664e9SAndroid Build Coastguard Worker setIsTextureView()222*d57664e9SAndroid Build Coastguard Worker void setIsTextureView() { mIsTextureView = true; } isTextureView()223*d57664e9SAndroid Build Coastguard Worker bool isTextureView() const { return mIsTextureView; } 224*d57664e9SAndroid Build Coastguard Worker 225*d57664e9SAndroid Build Coastguard Worker void markDrawStart(SkCanvas& canvas); 226*d57664e9SAndroid Build Coastguard Worker void markDrawEnd(SkCanvas& canvas); 227*d57664e9SAndroid Build Coastguard Worker 228*d57664e9SAndroid Build Coastguard Worker private: 229*d57664e9SAndroid Build Coastguard Worker void computeOrderingImpl(RenderNodeOp* opState, 230*d57664e9SAndroid Build Coastguard Worker std::vector<RenderNodeOp*>* compositedChildrenOfProjectionSurface, 231*d57664e9SAndroid Build Coastguard Worker const mat4* transformFromProjectionSurface); 232*d57664e9SAndroid Build Coastguard Worker 233*d57664e9SAndroid Build Coastguard Worker void syncProperties(); 234*d57664e9SAndroid Build Coastguard Worker void syncDisplayList(TreeObserver& observer, TreeInfo* info); 235*d57664e9SAndroid Build Coastguard Worker void handleForceDark(TreeInfo* info); 236*d57664e9SAndroid Build Coastguard Worker bool shouldEnableForceDark(TreeInfo* info); 237*d57664e9SAndroid Build Coastguard Worker bool isForceInvertDark(TreeInfo& info); 238*d57664e9SAndroid Build Coastguard Worker 239*d57664e9SAndroid Build Coastguard Worker void prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer); 240*d57664e9SAndroid Build Coastguard Worker void pushStagingPropertiesChanges(TreeInfo& info); 241*d57664e9SAndroid Build Coastguard Worker void pushStagingDisplayListChanges(TreeObserver& observer, TreeInfo& info); 242*d57664e9SAndroid Build Coastguard Worker void prepareLayer(TreeInfo& info, uint32_t dirtyMask); 243*d57664e9SAndroid Build Coastguard Worker void pushLayerUpdate(TreeInfo& info); 244*d57664e9SAndroid Build Coastguard Worker void deleteDisplayList(TreeObserver& observer, TreeInfo* info = nullptr); 245*d57664e9SAndroid Build Coastguard Worker void damageSelf(TreeInfo& info); 246*d57664e9SAndroid Build Coastguard Worker incParentRefCount()247*d57664e9SAndroid Build Coastguard Worker void incParentRefCount() { mParentCount++; } 248*d57664e9SAndroid Build Coastguard Worker void decParentRefCount(TreeObserver& observer, TreeInfo* info = nullptr); 249*d57664e9SAndroid Build Coastguard Worker 250*d57664e9SAndroid Build Coastguard Worker const int64_t mUniqueId; 251*d57664e9SAndroid Build Coastguard Worker String8 mName; 252*d57664e9SAndroid Build Coastguard Worker 253*d57664e9SAndroid Build Coastguard Worker uint32_t mDirtyPropertyFields; 254*d57664e9SAndroid Build Coastguard Worker RenderProperties mProperties; 255*d57664e9SAndroid Build Coastguard Worker RenderProperties mStagingProperties; 256*d57664e9SAndroid Build Coastguard Worker 257*d57664e9SAndroid Build Coastguard Worker // Owned by UI. Set when DL is set, cleared when DL cleared or when node detached 258*d57664e9SAndroid Build Coastguard Worker // (likely by parent re-record/removal) 259*d57664e9SAndroid Build Coastguard Worker bool mValid = false; 260*d57664e9SAndroid Build Coastguard Worker 261*d57664e9SAndroid Build Coastguard Worker bool mNeedsDisplayListSync; 262*d57664e9SAndroid Build Coastguard Worker // WARNING: Do not delete this directly, you must go through deleteDisplayList()! 263*d57664e9SAndroid Build Coastguard Worker DisplayList mDisplayList; 264*d57664e9SAndroid Build Coastguard Worker DisplayList mStagingDisplayList; 265*d57664e9SAndroid Build Coastguard Worker 266*d57664e9SAndroid Build Coastguard Worker int64_t mDamageGenerationId = 0; 267*d57664e9SAndroid Build Coastguard Worker 268*d57664e9SAndroid Build Coastguard Worker friend class AnimatorManager; 269*d57664e9SAndroid Build Coastguard Worker AnimatorManager mAnimatorManager; 270*d57664e9SAndroid Build Coastguard Worker 271*d57664e9SAndroid Build Coastguard Worker /** 272*d57664e9SAndroid Build Coastguard Worker * Draw time state - these properties are only set and used during rendering 273*d57664e9SAndroid Build Coastguard Worker */ 274*d57664e9SAndroid Build Coastguard Worker 275*d57664e9SAndroid Build Coastguard Worker // for projection surfaces, contains a list of all children items 276*d57664e9SAndroid Build Coastguard Worker std::vector<RenderNodeOp*> mProjectedNodes; 277*d57664e9SAndroid Build Coastguard Worker 278*d57664e9SAndroid Build Coastguard Worker // How many references our parent(s) have to us. Typically this should alternate 279*d57664e9SAndroid Build Coastguard Worker // between 2 and 1 (when a staging push happens we inc first then dec) 280*d57664e9SAndroid Build Coastguard Worker // When this hits 0 we are no longer in the tree, so any hardware resources 281*d57664e9SAndroid Build Coastguard Worker // (specifically Layers) should be released. 282*d57664e9SAndroid Build Coastguard Worker // This is *NOT* thread-safe, and should therefore only be tracking 283*d57664e9SAndroid Build Coastguard Worker // mDisplayList, not mStagingDisplayList. 284*d57664e9SAndroid Build Coastguard Worker uint32_t mParentCount; 285*d57664e9SAndroid Build Coastguard Worker 286*d57664e9SAndroid Build Coastguard Worker bool mPositionListenerDirty = false; 287*d57664e9SAndroid Build Coastguard Worker sp<PositionListener> mStagingPositionListener; 288*d57664e9SAndroid Build Coastguard Worker sp<PositionListener> mPositionListener; 289*d57664e9SAndroid Build Coastguard Worker 290*d57664e9SAndroid Build Coastguard Worker UsageHint mUsageHint = UsageHint::Unknown; 291*d57664e9SAndroid Build Coastguard Worker 292*d57664e9SAndroid Build Coastguard Worker bool mHasHolePunches; 293*d57664e9SAndroid Build Coastguard Worker StretchMask mStretchMask; 294*d57664e9SAndroid Build Coastguard Worker 295*d57664e9SAndroid Build Coastguard Worker bool mIsTextureView = false; 296*d57664e9SAndroid Build Coastguard Worker 297*d57664e9SAndroid Build Coastguard Worker // METHODS & FIELDS ONLY USED BY THE SKIA RENDERER 298*d57664e9SAndroid Build Coastguard Worker public: 299*d57664e9SAndroid Build Coastguard Worker /** 300*d57664e9SAndroid Build Coastguard Worker * Detach and transfer ownership of an already allocated displayList for use 301*d57664e9SAndroid Build Coastguard Worker * in recording updated content for this renderNode 302*d57664e9SAndroid Build Coastguard Worker */ detachAvailableList()303*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<skiapipeline::SkiaDisplayList> detachAvailableList() { 304*d57664e9SAndroid Build Coastguard Worker return std::move(mAvailableDisplayList); 305*d57664e9SAndroid Build Coastguard Worker } 306*d57664e9SAndroid Build Coastguard Worker hasHolePunches()307*d57664e9SAndroid Build Coastguard Worker bool hasHolePunches() { return mHasHolePunches; } 308*d57664e9SAndroid Build Coastguard Worker 309*d57664e9SAndroid Build Coastguard Worker /** 310*d57664e9SAndroid Build Coastguard Worker * Attach unused displayList to this node for potential future reuse. 311*d57664e9SAndroid Build Coastguard Worker */ attachAvailableList(skiapipeline::SkiaDisplayList * skiaDisplayList)312*d57664e9SAndroid Build Coastguard Worker void attachAvailableList(skiapipeline::SkiaDisplayList* skiaDisplayList) { 313*d57664e9SAndroid Build Coastguard Worker mAvailableDisplayList.reset(skiaDisplayList); 314*d57664e9SAndroid Build Coastguard Worker } 315*d57664e9SAndroid Build Coastguard Worker 316*d57664e9SAndroid Build Coastguard Worker /** 317*d57664e9SAndroid Build Coastguard Worker * Returns true if an offscreen layer from any renderPipeline is attached 318*d57664e9SAndroid Build Coastguard Worker * to this node. 319*d57664e9SAndroid Build Coastguard Worker */ hasLayer()320*d57664e9SAndroid Build Coastguard Worker bool hasLayer() const { return mSkiaLayer.get(); } 321*d57664e9SAndroid Build Coastguard Worker 322*d57664e9SAndroid Build Coastguard Worker /** 323*d57664e9SAndroid Build Coastguard Worker * Used by the RenderPipeline to attach an offscreen surface to the RenderNode. 324*d57664e9SAndroid Build Coastguard Worker * The surface is then will be used to store the contents of a layer. 325*d57664e9SAndroid Build Coastguard Worker */ setLayerSurface(sk_sp<SkSurface> layer)326*d57664e9SAndroid Build Coastguard Worker void setLayerSurface(sk_sp<SkSurface> layer) { 327*d57664e9SAndroid Build Coastguard Worker if (layer.get()) { 328*d57664e9SAndroid Build Coastguard Worker if (!mSkiaLayer.get()) { 329*d57664e9SAndroid Build Coastguard Worker mSkiaLayer = std::make_unique<skiapipeline::SkiaLayer>(); 330*d57664e9SAndroid Build Coastguard Worker } 331*d57664e9SAndroid Build Coastguard Worker mSkiaLayer->layerSurface = std::move(layer); 332*d57664e9SAndroid Build Coastguard Worker mSkiaLayer->inverseTransformInWindow.loadIdentity(); 333*d57664e9SAndroid Build Coastguard Worker } else { 334*d57664e9SAndroid Build Coastguard Worker mSkiaLayer.reset(); 335*d57664e9SAndroid Build Coastguard Worker } 336*d57664e9SAndroid Build Coastguard Worker 337*d57664e9SAndroid Build Coastguard Worker mProperties.mutateLayerProperties().mutableStretchEffect().clear(); 338*d57664e9SAndroid Build Coastguard Worker mStretchMask.clear(); 339*d57664e9SAndroid Build Coastguard Worker // Clear out the previous snapshot and the image filter the previous 340*d57664e9SAndroid Build Coastguard Worker // snapshot was created with whenever the layer changes. 341*d57664e9SAndroid Build Coastguard Worker mSnapshotResult.snapshot = nullptr; 342*d57664e9SAndroid Build Coastguard Worker mTargetImageFilter = nullptr; 343*d57664e9SAndroid Build Coastguard Worker } 344*d57664e9SAndroid Build Coastguard Worker 345*d57664e9SAndroid Build Coastguard Worker /** 346*d57664e9SAndroid Build Coastguard Worker * If the RenderNode is of type LayerType::RenderLayer then this method will 347*d57664e9SAndroid Build Coastguard Worker * return the an offscreen rendering surface that is used to both render into 348*d57664e9SAndroid Build Coastguard Worker * the layer and composite the layer into its parent. If the type is not 349*d57664e9SAndroid Build Coastguard Worker * LayerType::RenderLayer then it will return a nullptr. 350*d57664e9SAndroid Build Coastguard Worker * 351*d57664e9SAndroid Build Coastguard Worker * NOTE: this function is only guaranteed to return accurate results after 352*d57664e9SAndroid Build Coastguard Worker * prepareTree has been run for this RenderNode 353*d57664e9SAndroid Build Coastguard Worker */ getLayerSurface()354*d57664e9SAndroid Build Coastguard Worker SkSurface* getLayerSurface() const { 355*d57664e9SAndroid Build Coastguard Worker return mSkiaLayer.get() ? mSkiaLayer->layerSurface.get() : nullptr; 356*d57664e9SAndroid Build Coastguard Worker } 357*d57664e9SAndroid Build Coastguard Worker 358*d57664e9SAndroid Build Coastguard Worker struct SnapshotResult { 359*d57664e9SAndroid Build Coastguard Worker sk_sp<SkImage> snapshot; 360*d57664e9SAndroid Build Coastguard Worker SkIRect outSubset; 361*d57664e9SAndroid Build Coastguard Worker SkIPoint outOffset; 362*d57664e9SAndroid Build Coastguard Worker }; 363*d57664e9SAndroid Build Coastguard Worker 364*d57664e9SAndroid Build Coastguard Worker std::optional<SnapshotResult> updateSnapshotIfRequired(GrRecordingContext* context, 365*d57664e9SAndroid Build Coastguard Worker const SkImageFilter* imageFilter, 366*d57664e9SAndroid Build Coastguard Worker const SkIRect& clipBounds); 367*d57664e9SAndroid Build Coastguard Worker getSkiaLayer()368*d57664e9SAndroid Build Coastguard Worker skiapipeline::SkiaLayer* getSkiaLayer() const { return mSkiaLayer.get(); } 369*d57664e9SAndroid Build Coastguard Worker 370*d57664e9SAndroid Build Coastguard Worker /** 371*d57664e9SAndroid Build Coastguard Worker * Returns the path that represents the outline of RenderNode intersected with 372*d57664e9SAndroid Build Coastguard Worker * the provided rect. This call will internally cache the resulting path in 373*d57664e9SAndroid Build Coastguard Worker * order to potentially return that path for subsequent calls to this method. 374*d57664e9SAndroid Build Coastguard Worker * By reusing the same path we get better performance on the GPU backends since 375*d57664e9SAndroid Build Coastguard Worker * those resources are cached in the hardware based on the path's genID. 376*d57664e9SAndroid Build Coastguard Worker * 377*d57664e9SAndroid Build Coastguard Worker * The returned path is only guaranteed to be valid until this function is called 378*d57664e9SAndroid Build Coastguard Worker * again or the RenderNode's outline is mutated. 379*d57664e9SAndroid Build Coastguard Worker */ 380*d57664e9SAndroid Build Coastguard Worker const SkPath* getClippedOutline(const SkRect& clipRect) const; 381*d57664e9SAndroid Build Coastguard Worker 382*d57664e9SAndroid Build Coastguard Worker private: 383*d57664e9SAndroid Build Coastguard Worker /** 384*d57664e9SAndroid Build Coastguard Worker * If this RenderNode has been used in a previous frame then the SkiaDisplayList 385*d57664e9SAndroid Build Coastguard Worker * from that frame is cached here until one of the following conditions is met: 386*d57664e9SAndroid Build Coastguard Worker * 1) The RenderNode is deleted (causing this to be deleted) 387*d57664e9SAndroid Build Coastguard Worker * 2) It is replaced with the displayList from the next completed frame 388*d57664e9SAndroid Build Coastguard Worker * 3) It is detached and used to to record a new displayList for a later frame 389*d57664e9SAndroid Build Coastguard Worker */ 390*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<skiapipeline::SkiaDisplayList> mAvailableDisplayList; 391*d57664e9SAndroid Build Coastguard Worker 392*d57664e9SAndroid Build Coastguard Worker /** 393*d57664e9SAndroid Build Coastguard Worker * An offscreen rendering target used to contain the contents this RenderNode 394*d57664e9SAndroid Build Coastguard Worker * when it has been set to draw as a LayerType::RenderLayer. 395*d57664e9SAndroid Build Coastguard Worker */ 396*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<skiapipeline::SkiaLayer> mSkiaLayer; 397*d57664e9SAndroid Build Coastguard Worker 398*d57664e9SAndroid Build Coastguard Worker /** 399*d57664e9SAndroid Build Coastguard Worker * SkImageFilter used to create the mSnapshotResult 400*d57664e9SAndroid Build Coastguard Worker */ 401*d57664e9SAndroid Build Coastguard Worker sk_sp<SkImageFilter> mTargetImageFilter; 402*d57664e9SAndroid Build Coastguard Worker uint32_t mTargetImageFilterLayerSurfaceGenerationId = 0; 403*d57664e9SAndroid Build Coastguard Worker 404*d57664e9SAndroid Build Coastguard Worker /** 405*d57664e9SAndroid Build Coastguard Worker * Clip bounds used to create the mSnapshotResult 406*d57664e9SAndroid Build Coastguard Worker */ 407*d57664e9SAndroid Build Coastguard Worker SkIRect mImageFilterClipBounds; 408*d57664e9SAndroid Build Coastguard Worker 409*d57664e9SAndroid Build Coastguard Worker /** 410*d57664e9SAndroid Build Coastguard Worker * Result of the most recent snapshot with additional metadata used to 411*d57664e9SAndroid Build Coastguard Worker * determine how to draw the contents 412*d57664e9SAndroid Build Coastguard Worker */ 413*d57664e9SAndroid Build Coastguard Worker SnapshotResult mSnapshotResult; 414*d57664e9SAndroid Build Coastguard Worker 415*d57664e9SAndroid Build Coastguard Worker struct ClippedOutlineCache { 416*d57664e9SAndroid Build Coastguard Worker // keys 417*d57664e9SAndroid Build Coastguard Worker uint32_t outlineID = 0; 418*d57664e9SAndroid Build Coastguard Worker SkRect clipRect; 419*d57664e9SAndroid Build Coastguard Worker 420*d57664e9SAndroid Build Coastguard Worker // value 421*d57664e9SAndroid Build Coastguard Worker SkPath clippedOutline; 422*d57664e9SAndroid Build Coastguard Worker }; 423*d57664e9SAndroid Build Coastguard Worker mutable ClippedOutlineCache mClippedOutlineCache; 424*d57664e9SAndroid Build Coastguard Worker }; // class RenderNode 425*d57664e9SAndroid Build Coastguard Worker 426*d57664e9SAndroid Build Coastguard Worker class MarkAndSweepRemoved : public TreeObserver { 427*d57664e9SAndroid Build Coastguard Worker PREVENT_COPY_AND_ASSIGN(MarkAndSweepRemoved); 428*d57664e9SAndroid Build Coastguard Worker 429*d57664e9SAndroid Build Coastguard Worker public: MarkAndSweepRemoved(TreeInfo * info)430*d57664e9SAndroid Build Coastguard Worker explicit MarkAndSweepRemoved(TreeInfo* info) : mTreeInfo(info) {} 431*d57664e9SAndroid Build Coastguard Worker onMaybeRemovedFromTree(RenderNode * node)432*d57664e9SAndroid Build Coastguard Worker void onMaybeRemovedFromTree(RenderNode* node) override { mMarked.emplace_back(node); } 433*d57664e9SAndroid Build Coastguard Worker ~MarkAndSweepRemoved()434*d57664e9SAndroid Build Coastguard Worker ~MarkAndSweepRemoved() { 435*d57664e9SAndroid Build Coastguard Worker for (auto& node : mMarked) { 436*d57664e9SAndroid Build Coastguard Worker if (!node->hasParents()) { 437*d57664e9SAndroid Build Coastguard Worker node->onRemovedFromTree(mTreeInfo); 438*d57664e9SAndroid Build Coastguard Worker } 439*d57664e9SAndroid Build Coastguard Worker } 440*d57664e9SAndroid Build Coastguard Worker } 441*d57664e9SAndroid Build Coastguard Worker 442*d57664e9SAndroid Build Coastguard Worker private: 443*d57664e9SAndroid Build Coastguard Worker FatVector<sp<RenderNode>, 10> mMarked; 444*d57664e9SAndroid Build Coastguard Worker TreeInfo* mTreeInfo; 445*d57664e9SAndroid Build Coastguard Worker }; 446*d57664e9SAndroid Build Coastguard Worker 447*d57664e9SAndroid Build Coastguard Worker } /* namespace uirenderer */ 448*d57664e9SAndroid Build Coastguard Worker } /* namespace android */ 449