• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
58     // Constructor for unbounded ops *with* transform/clip
59     ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
60             const Matrix4& localTransform, const ClipBase* localClip);
61 
62     // Constructor for unbounded ops without transform/clip (namely shadows)
63     ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot);
64 
65     // Constructor for primitive ops provided clip, and no transform
66     ResolvedRenderState(const ClipRect* viewportRect, const Rect& dstRect);
67 
computeLocalSpaceClip()68     Rect computeLocalSpaceClip() const {
69         Matrix4 inverse;
70         inverse.loadInverse(transform);
71 
72         Rect outClip(clipRect());
73         inverse.mapRect(outClip);
74         return outClip;
75     }
76 
clipRect()77     const Rect& clipRect() const {
78         return clipState->rect;
79     }
80 
requiresClip()81     bool requiresClip() const {
82         return clipSideFlags != OpClipSideFlags::None
83                || CC_UNLIKELY(clipState->mode != ClipMode::Rectangle);
84     }
85 
86     // returns the clip if it's needed to draw the operation, otherwise nullptr
getClipIfNeeded()87     const ClipBase* getClipIfNeeded() const {
88         return requiresClip() ? clipState : nullptr;
89     }
90 
91     Matrix4 transform;
92     const ClipBase* clipState = nullptr;
93     Rect clippedBounds;
94     int clipSideFlags = 0;
95     const SkPath* localProjectionPathMask = nullptr;
96     bool opaqueOverClippedBounds = false;
97 };
98 
99 /**
100  * Self-contained op wrapper, containing all resolved state required to draw the op.
101  *
102  * Stashed pointers within all point to longer lived objects, with no ownership implied.
103  */
104 class BakedOpState {
105 public:
106     static BakedOpState* tryConstruct(LinearAllocator& allocator,
107             Snapshot& snapshot, const RecordedOp& recordedOp);
108 
109     static BakedOpState* tryConstructUnbounded(LinearAllocator& allocator,
110             Snapshot& snapshot, const RecordedOp& recordedOp);
111 
112     enum class StrokeBehavior {
113         // stroking is forced, regardless of style on paint (such as for lines)
114         Forced,
115         // stroking is defined by style on paint
116         StyleDefined,
117     };
118 
119     static BakedOpState* tryStrokeableOpConstruct(LinearAllocator& allocator,
120             Snapshot& snapshot, const RecordedOp& recordedOp, StrokeBehavior strokeBehavior);
121 
122     static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator,
123             Snapshot& snapshot, const ShadowOp* shadowOpPtr);
124 
125     static BakedOpState* directConstruct(LinearAllocator& allocator,
126             const ClipRect* clip, const Rect& dstRect, const RecordedOp& recordedOp);
127 
128     // Set opaqueOverClippedBounds. If this method isn't called, the op is assumed translucent.
129     void setupOpacity(const SkPaint* paint);
130 
131     // computed state:
132     ResolvedRenderState computedState;
133 
134     // simple state (straight pointer/value storage):
135     const float alpha;
136     const RoundRectClipState* roundRectClipState;
137     const RecordedOp* op;
138 
139 private:
140     friend class LinearAllocator;
141 
BakedOpState(LinearAllocator & allocator,Snapshot & snapshot,const RecordedOp & recordedOp,bool expandForStroke)142     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot,
143             const RecordedOp& recordedOp, bool expandForStroke)
144             : computedState(allocator, snapshot, recordedOp, expandForStroke)
145             , alpha(snapshot.alpha)
146             , roundRectClipState(snapshot.roundRectClipState)
147             , op(&recordedOp) {}
148 
149     // TODO: fix this brittleness
BakedOpState(LinearAllocator & allocator,Snapshot & snapshot,const RecordedOp & recordedOp)150     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp)
151             : computedState(allocator, snapshot, recordedOp.localMatrix, recordedOp.localClip)
152             , alpha(snapshot.alpha)
153             , roundRectClipState(snapshot.roundRectClipState)
154             , op(&recordedOp) {}
155 
BakedOpState(LinearAllocator & allocator,Snapshot & snapshot,const ShadowOp * shadowOpPtr)156     BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr)
157             : computedState(allocator, snapshot)
158             , alpha(snapshot.alpha)
159             , roundRectClipState(snapshot.roundRectClipState)
160             , op(shadowOpPtr) {}
161 
BakedOpState(const ClipRect * clipRect,const Rect & dstRect,const RecordedOp & recordedOp)162     BakedOpState(const ClipRect* clipRect, const Rect& dstRect, const RecordedOp& recordedOp)
163             : computedState(clipRect, dstRect)
164             , alpha(1.0f)
165             , roundRectClipState(nullptr)
166             , op(&recordedOp) {}
167 };
168 
169 }; // namespace uirenderer
170 }; // namespace android
171 
172 #endif // ANDROID_HWUI_BAKED_OP_STATE_H
173