CanvasState.h revision 64e445bf74bee2098781d608cedfd723d8cc88d3
1984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson/*
2984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Copyright (C) 2014 The Android Open Source Project
3984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson *
4984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Licensed under the Apache License, Version 2.0 (the "License");
5984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * you may not use this file except in compliance with the License.
6984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * You may obtain a copy of the License at
7984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson *
8984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson *      http://www.apache.org/licenses/LICENSE-2.0
9984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson *
10984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Unless required by applicable law or agreed to in writing, software
11984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * distributed under the License is distributed on an "AS IS" BASIS,
12984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * See the License for the specific language governing permissions and
14984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * limitations under the License.
15984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */
16984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
17984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#ifndef ANDROID_HWUI_CANVAS_STATE_H
18984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#define ANDROID_HWUI_CANVAS_STATE_H
19984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
20984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include <SkMatrix.h>
21984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include <SkPath.h>
22984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include <SkRegion.h>
23984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
24984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#include "Snapshot.h"
25984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
26984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonnamespace android {
27984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonnamespace uirenderer {
28984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
29984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson/**
30984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Abstract base class for any class containing CanvasState.
31984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Defines three mandatory callbacks.
32984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */
33984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonclass CanvasStateClient {
34984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonpublic:
35984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    CanvasStateClient() { }
36984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    virtual ~CanvasStateClient() { }
37984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
38984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /**
39984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Callback allowing embedder to take actions in the middle of a
40984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * setViewport() call.
41984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     */
42984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    virtual void onViewportInitialized() = 0;
43984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
44984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /**
45984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Callback allowing embedder to take actions in the middle of a
46984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * restore() call.  May be called several times sequentially.
47984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     */
48984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0;
49984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
50984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /**
51984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Allows subclasses to control what value is stored in snapshot's
52984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * fbo field in * initializeSaveStack.
53984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     */
546b109c74982033d4a220cd10a0eab8b024b351c9Chris Craik    virtual GLuint getTargetFbo() const = 0;
55984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
56984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // class CanvasStateClient
57984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
58984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson/**
59984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Implements Canvas state methods on behalf of Renderers.
60984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson *
61984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the
62984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Renderer interface. Drawing and recording classes that include a CanvasState will have
63984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * different use cases:
64984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson *
65db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * Drawing code maintaining canvas state (i.e. OpenGLRenderer) can query attributes (such as
66db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * transform) or hook into changes (e.g. save/restore) with minimal surface area for manipulating
67db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * the stack itself.
68984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson *
69db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * Recording code maintaining canvas state (i.e. DisplayListCanvas) can both record and pass
70db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * through state operations to CanvasState, so that not only will querying operations work
71db663fe83f976107fd8fd9307d871b37d9e47370Chris Craik * (getClip/Matrix), but so that quickRejection can also be used.
72984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */
73984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
7464e445bf74bee2098781d608cedfd723d8cc88d3Chris Craikclass CanvasState {
75984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonpublic:
76984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    CanvasState(CanvasStateClient& renderer);
77984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
78984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /**
79984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Initializes the first snapshot, computing the projection matrix,
80984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * and stores the dimensions of the render target.
81984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     */
8264e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik    void initializeSaveStack(int viewportWidth, int viewportHeight,
8364e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik            float clipLeft, float clipTop, float clipRight, float clipBottom,
84984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson            const Vector3& lightCenter);
85984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
86984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool hasRectToRectTransform() const {
87984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson        return CC_LIKELY(currentTransform()->rectToRect());
88984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    }
89984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
90984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    // Save (layer)
91984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int getSaveCount() const { return mSaveCount; }
92984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int save(int flags);
93984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void restore();
94984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void restoreToCount(int saveCount);
95984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
96984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    // Save/Restore without side-effects
97984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int saveSnapshot(int flags);
98984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void restoreSnapshot();
99984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
100984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    // Matrix
101984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void getMatrix(SkMatrix* outMatrix) const;
102984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void translate(float dx, float dy, float dz = 0.0f);
103984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void rotate(float degrees);
104984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void scale(float sx, float sy);
105984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void skew(float sx, float sy);
106984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
107984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setMatrix(const SkMatrix& matrix);
108984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setMatrix(const Matrix4& matrix); // internal only convenience method
109984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void concatMatrix(const SkMatrix& matrix);
110984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void concatMatrix(const Matrix4& matrix); // internal only convenience method
111984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
112984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    // Clip
113984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); }
114984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); }
115984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
116984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool quickRejectConservative(float left, float top, float right, float bottom) const;
117984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
118984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
119984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool clipPath(const SkPath* path, SkRegion::Op op);
120984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool clipRegion(const SkRegion* region, SkRegion::Op op);
121984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
122984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /**
123984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Sets a "clipping outline", which is independent from the regular clip.
124984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Currently only supports rectangles or rounded rectangles; passing in a
125984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * more complicated outline fails silently. Replaces any previous clipping
126984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * outline.
127984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     */
128984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
129984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setClippingRoundRect(LinearAllocator& allocator,
130984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson            const Rect& rect, float radius, bool highPriority = true);
131fca52b7583d1e5f5ff8ed06554875d2a30ef56faChris Craik    void setProjectionPathMask(LinearAllocator& allocator, const SkPath* path);
132984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
133984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /**
134984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Returns true if drawing in the rectangle (left, top, right, bottom)
135984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * will be clipped out. Is conservative: might return false when subpixel-
136984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * perfect tests would return true.
137984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     */
138984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
139984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson            bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const;
140984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
141984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setDirtyClip(bool opaque) { mDirtyClip = opaque; }
142984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool getDirtyClip() const { return mDirtyClip; }
143984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
144984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; }
145984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setEmpty(bool value) { mSnapshot->empty = value; }
146984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setInvisible(bool value) { mSnapshot->invisible = value; }
147984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
148984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline const mat4* currentTransform() const { return currentSnapshot()->transform; }
149487a92caef2eb90a62e8f8d7a6fe6315f1c1d8d8Rob Tsuk    inline const Rect& currentClipRect() const { return currentSnapshot()->getClipRect(); }
150984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline Region* currentRegion() const { return currentSnapshot()->region; }
151984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline int currentFlags() const { return currentSnapshot()->flags; }
152984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); }
153984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); }
154984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); }
155984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); }
156a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik    int getWidth() const { return mWidth; }
157a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik    int getHeight() const { return mHeight; }
158a766cb2bce5db9108c0266fbebea6aa18d5713ffChris Craik    bool clipIsSimple() const { return currentSnapshot()->clipIsSimple(); }
159984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
16064e445bf74bee2098781d608cedfd723d8cc88d3Chris Craik    inline const Snapshot* currentSnapshot() const { return mSnapshot.get(); }
161984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline Snapshot* writableSnapshot() { return mSnapshot.get(); }
162984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); }
163984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
164984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonprivate:
165984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// indicates that the clip has been changed since the last time it was consumed
166984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool mDirtyClip;
167984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
168984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Dimensions of the drawing surface
169984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int mWidth, mHeight;
170984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
171984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Number of saved states
172984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int mSaveCount;
173984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
174984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Base state
175984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    sp<Snapshot> mFirstSnapshot;
176984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
177984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Host providing callbacks
178984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    CanvasStateClient& mCanvas;
179984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
180984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Current state
181984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    sp<Snapshot> mSnapshot;
182984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
183984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // class CanvasState
184984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
185984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // namespace uirenderer
186984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // namespace android
187984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
188984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#endif // ANDROID_HWUI_CANVAS_STATE_H
189