1b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/*
2b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Copyright (C) 2015 The Android Open Source Project
3b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
4b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Licensed under the Apache License, Version 2.0 (the "License");
5b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * you may not use this file except in compliance with the License.
6b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * You may obtain a copy of the License at
7b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
8b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *      http://www.apache.org/licenses/LICENSE-2.0
9b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
10b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Unless required by applicable law or agreed to in writing, software
11b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * distributed under the License is distributed on an "AS IS" BASIS,
12b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * See the License for the specific language governing permissions and
14b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * limitations under the License.
15b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */
16b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
17b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#ifndef ANDROID_HWUI_BAKED_OP_STATE_H
18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#define ANDROID_HWUI_BAKED_OP_STATE_H
19b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
20b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "Matrix.h"
21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "RecordedOp.h"
22b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "Rect.h"
23b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "Snapshot.h"
24b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace android {
26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace uirenderer {
27b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
28b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace OpClipSideFlags {
29b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    enum {
30b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        None = 0x0,
31b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Left = 0x1,
32b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Top = 0x2,
33b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Right = 0x4,
34b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Bottom = 0x8,
35b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Full = 0xF,
36b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        // ConservativeFull = 0x1F  needed?
37b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    };
38b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
39b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
40b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/**
4115c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik * Holds a list of BakedOpStates of ops that can be drawn together
4215c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik */
4315c3f19a445b8df575911a16e8a6dba755a084b5Chris Craikstruct MergedBakedOpList {
4415c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik    const BakedOpState*const* states;
4515c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik    size_t count;
4615c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik    int clipSideFlags;
4715c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik    Rect clip;
4815c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik};
4915c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik
5015c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik/**
51b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Holds the resolved clip, transform, and bounds of a recordedOp, when replayed with a snapshot
52b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */
53b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass ResolvedRenderState {
54b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikpublic:
55e4db79de127cfe961195f52907af8451026eaa20Chris Craik    ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
5649b403dc9c47ada51c8e5b883347682a868515f8Chris Craik            const RecordedOp& recordedOp, bool expandForStroke, bool expandForPathTexture);
57b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
584c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik    // Constructor for unbounded ops *with* transform/clip
594c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik    ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot,
604c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik            const Matrix4& localTransform, const ClipBase* localClip);
614c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik
62e4db79de127cfe961195f52907af8451026eaa20Chris Craik    // Constructor for unbounded ops without transform/clip (namely shadows)
63e4db79de127cfe961195f52907af8451026eaa20Chris Craik    ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot);
64d3daa3198e2212c985c634821682d5819346b653Chris Craik
657435eb148e72382126e9073183e881357bb38a8bChris Craik    // Constructor for primitive ops provided clip, and no transform
667435eb148e72382126e9073183e881357bb38a8bChris Craik    ResolvedRenderState(const ClipRect* viewportRect, const Rect& dstRect);
67b87eadda1818034ce03d85f30388384d1ac65916Chris Craik
68d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    Rect computeLocalSpaceClip() const {
69d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        Matrix4 inverse;
70d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        inverse.loadInverse(transform);
71d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik
72e4db79de127cfe961195f52907af8451026eaa20Chris Craik        Rect outClip(clipRect());
73d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        inverse.mapRect(outClip);
74d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        return outClip;
75d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    }
76d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik
77e4db79de127cfe961195f52907af8451026eaa20Chris Craik    const Rect& clipRect() const {
78e4db79de127cfe961195f52907af8451026eaa20Chris Craik        return clipState->rect;
79e4db79de127cfe961195f52907af8451026eaa20Chris Craik    }
80b87eadda1818034ce03d85f30388384d1ac65916Chris Craik
81e4db79de127cfe961195f52907af8451026eaa20Chris Craik    bool requiresClip() const {
82e4db79de127cfe961195f52907af8451026eaa20Chris Craik        return clipSideFlags != OpClipSideFlags::None
837435eb148e72382126e9073183e881357bb38a8bChris Craik               || CC_UNLIKELY(clipState->mode != ClipMode::Rectangle);
84e4db79de127cfe961195f52907af8451026eaa20Chris Craik    }
85e4db79de127cfe961195f52907af8451026eaa20Chris Craik
86e4db79de127cfe961195f52907af8451026eaa20Chris Craik    // returns the clip if it's needed to draw the operation, otherwise nullptr
87e4db79de127cfe961195f52907af8451026eaa20Chris Craik    const ClipBase* getClipIfNeeded() const {
88e4db79de127cfe961195f52907af8451026eaa20Chris Craik        return requiresClip() ? clipState : nullptr;
89e4db79de127cfe961195f52907af8451026eaa20Chris Craik    }
90b87eadda1818034ce03d85f30388384d1ac65916Chris Craik
91b87eadda1818034ce03d85f30388384d1ac65916Chris Craik    Matrix4 transform;
92e4db79de127cfe961195f52907af8451026eaa20Chris Craik    const ClipBase* clipState = nullptr;
93b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    Rect clippedBounds;
94b87eadda1818034ce03d85f30388384d1ac65916Chris Craik    int clipSideFlags = 0;
95678ff81105753656aa4822f4f675ef96dc9d2b83Chris Craik    const SkPath* localProjectionPathMask = nullptr;
9680d2ade939153da87b3cd3b0a69a713bf68b64baChris Craik    bool opaqueOverClippedBounds = false;
97b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik};
98b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
99b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/**
100b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Self-contained op wrapper, containing all resolved state required to draw the op.
101b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik *
102b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Stashed pointers within all point to longer lived objects, with no ownership implied.
103b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */
104b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass BakedOpState {
105b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikpublic:
106b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    static BakedOpState* tryConstruct(LinearAllocator& allocator,
10780d2ade939153da87b3cd3b0a69a713bf68b64baChris Craik            Snapshot& snapshot, const RecordedOp& recordedOp);
108386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
1094c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik    static BakedOpState* tryConstructUnbounded(LinearAllocator& allocator,
11080d2ade939153da87b3cd3b0a69a713bf68b64baChris Craik            Snapshot& snapshot, const RecordedOp& recordedOp);
1114c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik
112386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    enum class StrokeBehavior {
1134c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik        // stroking is forced, regardless of style on paint (such as for lines)
114386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        Forced,
115386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        // stroking is defined by style on paint
116386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik        StyleDefined,
117386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    };
118386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik
119386aa031793bb037ec43b6cdbd8908c343cc86cbChris Craik    static BakedOpState* tryStrokeableOpConstruct(LinearAllocator& allocator,
12049b403dc9c47ada51c8e5b883347682a868515f8Chris Craik            Snapshot& snapshot, const RecordedOp& recordedOp, StrokeBehavior strokeBehavior,
12149b403dc9c47ada51c8e5b883347682a868515f8Chris Craik            bool expandForPathTexture);
122b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
123d3daa3198e2212c985c634821682d5819346b653Chris Craik    static BakedOpState* tryShadowOpConstruct(LinearAllocator& allocator,
12480d2ade939153da87b3cd3b0a69a713bf68b64baChris Craik            Snapshot& snapshot, const ShadowOp* shadowOpPtr);
125d3daa3198e2212c985c634821682d5819346b653Chris Craik
126b87eadda1818034ce03d85f30388384d1ac65916Chris Craik    static BakedOpState* directConstruct(LinearAllocator& allocator,
12780d2ade939153da87b3cd3b0a69a713bf68b64baChris Craik            const ClipRect* clip, const Rect& dstRect, const RecordedOp& recordedOp);
12880d2ade939153da87b3cd3b0a69a713bf68b64baChris Craik
12980d2ade939153da87b3cd3b0a69a713bf68b64baChris Craik    // Set opaqueOverClippedBounds. If this method isn't called, the op is assumed translucent.
13080d2ade939153da87b3cd3b0a69a713bf68b64baChris Craik    void setupOpacity(const SkPaint* paint);
131b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
132b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // computed state:
133b87eadda1818034ce03d85f30388384d1ac65916Chris Craik    ResolvedRenderState computedState;
134b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
135b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    // simple state (straight pointer/value storage):
136b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    const float alpha;
137b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    const RoundRectClipState* roundRectClipState;
138b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    const RecordedOp* op;
139b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
140b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikprivate:
1417df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck    friend class LinearAllocator;
1427df9ff2a08fd4bbd9b2e734a357cffcf64675df9John Reck
143e4db79de127cfe961195f52907af8451026eaa20Chris Craik    BakedOpState(LinearAllocator& allocator, Snapshot& snapshot,
14449b403dc9c47ada51c8e5b883347682a868515f8Chris Craik            const RecordedOp& recordedOp, bool expandForStroke, bool expandForPathTexture)
14549b403dc9c47ada51c8e5b883347682a868515f8Chris Craik            : computedState(allocator, snapshot, recordedOp, expandForStroke, expandForPathTexture)
146b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            , alpha(snapshot.alpha)
147b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            , roundRectClipState(snapshot.roundRectClipState)
148b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            , op(&recordedOp) {}
149d3daa3198e2212c985c634821682d5819346b653Chris Craik
1504c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik    // TODO: fix this brittleness
1514c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik    BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const RecordedOp& recordedOp)
1524c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik            : computedState(allocator, snapshot, recordedOp.localMatrix, recordedOp.localClip)
1534c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik            , alpha(snapshot.alpha)
1544c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik            , roundRectClipState(snapshot.roundRectClipState)
1554c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik            , op(&recordedOp) {}
1564c3980b6e43cc7c0541f54b8e7e2d9d6108be622Chris Craik
157e4db79de127cfe961195f52907af8451026eaa20Chris Craik    BakedOpState(LinearAllocator& allocator, Snapshot& snapshot, const ShadowOp* shadowOpPtr)
158e4db79de127cfe961195f52907af8451026eaa20Chris Craik            : computedState(allocator, snapshot)
159d3daa3198e2212c985c634821682d5819346b653Chris Craik            , alpha(snapshot.alpha)
160d3daa3198e2212c985c634821682d5819346b653Chris Craik            , roundRectClipState(snapshot.roundRectClipState)
161d3daa3198e2212c985c634821682d5819346b653Chris Craik            , op(shadowOpPtr) {}
162b87eadda1818034ce03d85f30388384d1ac65916Chris Craik
1634876de16e34622634266d09522c9153c78c7c2fbChris Craik    BakedOpState(const ClipRect* clipRect, const Rect& dstRect, const RecordedOp& recordedOp)
1644876de16e34622634266d09522c9153c78c7c2fbChris Craik            : computedState(clipRect, dstRect)
165b87eadda1818034ce03d85f30388384d1ac65916Chris Craik            , alpha(1.0f)
166b87eadda1818034ce03d85f30388384d1ac65916Chris Craik            , roundRectClipState(nullptr)
167b87eadda1818034ce03d85f30388384d1ac65916Chris Craik            , op(&recordedOp) {}
168b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik};
169b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
170b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}; // namespace uirenderer
171b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}; // namespace android
172b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
173b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif // ANDROID_HWUI_BAKED_OP_STATE_H
174