1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_HWUI_BAKED_OP_STATE_H 18 #define ANDROID_HWUI_BAKED_OP_STATE_H 19 20 #include "Matrix.h" 21 #include "RecordedOp.h" 22 #include "Rect.h" 23 #include "Snapshot.h" 24 25 namespace android { 26 namespace uirenderer { 27 28 namespace OpClipSideFlags { 29 enum { 30 None = 0x0, 31 Left = 0x1, 32 Top = 0x2, 33 Right = 0x4, 34 Bottom = 0x8, 35 Full = 0xF, 36 // ConservativeFull = 0x1F needed? 37 }; 38 } 39 40 /** 41 * Holds a list of BakedOpStates of ops that can be drawn together 42 */ 43 struct MergedBakedOpList { 44 const BakedOpState* const* states; 45 size_t count; 46 int clipSideFlags; 47 Rect clip; 48 }; 49 50 /** 51 * Holds the resolved clip, transform, and bounds of a recordedOp, when replayed with a snapshot 52 */ 53 class ResolvedRenderState { 54 public: 55 ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot, 56 const RecordedOp& recordedOp, bool expandForStroke, 57 bool expandForPathTexture); 58 59 // Constructor for unbounded ops *with* transform/clip 60 ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot, 61 const Matrix4& localTransform, const ClipBase* localClip); 62 63 // Constructor for unbounded ops without transform/clip (namely shadows) 64 ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot); 65 66 // Constructor for primitive ops provided clip, and no transform 67 ResolvedRenderState(const ClipRect* viewportRect, const Rect& dstRect); 68 computeLocalSpaceClip()69 Rect computeLocalSpaceClip() const { 70 Matrix4 inverse; 71 inverse.loadInverse(transform); 72 73 Rect outClip(clipRect()); 74 inverse.mapRect(outClip); 75 return outClip; 76 } 77 clipRect()78 const Rect& clipRect() const { return clipState->rect; } 79 requiresClip()80 bool requiresClip() const { 81 return clipSideFlags != OpClipSideFlags::None || 82 CC_UNLIKELY(clipState->mode != ClipMode::Rectangle); 83 } 84 85 // returns the clip if it's needed to draw the operation, otherwise nullptr getClipIfNeeded()86 const ClipBase* getClipIfNeeded() const { return requiresClip() ? clipState : nullptr; } 87 88 Matrix4 transform; 89 const ClipBase* clipState = nullptr; 90 Rect clippedBounds; 91 int clipSideFlags = 0; 92 const SkPath* localProjectionPathMask = nullptr; 93 bool opaqueOverClippedBounds = false; 94 }; 95 96 /** 97 * Self-contained op wrapper, containing all resolved state required to draw the op. 98 * 99 * Stashed pointers within all point to longer lived objects, with no ownership implied. 100 */ 101 class BakedOpState { 102 public: 103 static BakedOpState* tryConstruct(LinearAllocator& allocator, Snapshot& snapshot, 104 const RecordedOp& recordedOp); 105 106 static BakedOpState* tryConstructUnbounded(LinearAllocator& allocator, Snapshot& snapshot, 107 const RecordedOp& recordedOp); 108 109 enum class StrokeBehavior { 110 // stroking is forced, regardless of style on paint (such as for lines) 111 Forced, 112 // stroking is defined by style on paint 113 StyleDefined, 114 }; 115 116 static BakedOpState* tryStrokeableOpConstruct(LinearAllocator& allocator, Snapshot& snapshot, 117 const RecordedOp& recordedOp, 118 StrokeBehavior strokeBehavior, 119 bool expandForPathTexture); 120 121 static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator, Snapshot& snapshot, 122 const ShadowOp* shadowOpPtr); 123 124 static BakedOpState* directConstruct(LinearAllocator& allocator, const ClipRect* clip, 125 const Rect& dstRect, const RecordedOp& recordedOp); 126 127 // Set opaqueOverClippedBounds. If this method isn't called, the op is assumed translucent. 128 void setupOpacity(const SkPaint* paint); 129 130 // computed state: 131 ResolvedRenderState computedState; 132 133 // simple state (straight pointer/value storage): 134 const float alpha; 135 const RoundRectClipState* roundRectClipState; 136 const RecordedOp* op; 137 138 private: 139 friend class LinearAllocator; 140 BakedOpState(LinearAllocator & allocator,Snapshot & snapshot,const RecordedOp & recordedOp,bool expandForStroke,bool expandForPathTexture)141 BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp, 142 bool expandForStroke, bool expandForPathTexture) 143 : computedState(allocator, snapshot, recordedOp, expandForStroke, expandForPathTexture) 144 , alpha(snapshot.alpha) 145 , roundRectClipState(snapshot.roundRectClipState) 146 , op(&recordedOp) {} 147 148 // TODO: fix this brittleness BakedOpState(LinearAllocator & allocator,Snapshot & snapshot,const RecordedOp & recordedOp)149 BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp) 150 : computedState(allocator, snapshot, recordedOp.localMatrix, recordedOp.localClip) 151 , alpha(snapshot.alpha) 152 , roundRectClipState(snapshot.roundRectClipState) 153 , op(&recordedOp) {} 154 BakedOpState(LinearAllocator & allocator,Snapshot & snapshot,const ShadowOp * shadowOpPtr)155 BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr) 156 : computedState(allocator, snapshot) 157 , alpha(snapshot.alpha) 158 , roundRectClipState(snapshot.roundRectClipState) 159 , op(shadowOpPtr) {} 160 BakedOpState(const ClipRect * clipRect,const Rect & dstRect,const RecordedOp & recordedOp)161 BakedOpState(const ClipRect* clipRect, const Rect& dstRect, const RecordedOp& recordedOp) 162 : computedState(clipRect, dstRect) 163 , alpha(1.0f) 164 , roundRectClipState(nullptr) 165 , op(&recordedOp) {} 166 }; 167 168 }; // namespace uirenderer 169 }; // namespace android 170 171 #endif // ANDROID_HWUI_BAKED_OP_STATE_H 172