CanvasState.h revision e84a208317e0ed388fcdad1e6743c7849acb51b0
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     */
54984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    virtual GLuint onGetTargetFbo() 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 *
65984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into
66984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself.
67984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson *
68984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations
69984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * to CanvasState, so that not only will querying operations work (getClip/Matrix), but so
70984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson * that quickRejection can also be used.
71984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson */
72984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
73f59b8f0d7c9fe24253a1d9e85f59601d244ec978Dan Albertclass ANDROID_API CanvasState {
74984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonpublic:
75984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    CanvasState(CanvasStateClient& renderer);
76984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    ~CanvasState();
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     */
82984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom,
83984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson            const Vector3& lightCenter);
84984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
85984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setViewport(int width, int height);
86984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
87984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool hasRectToRectTransform() const {
88984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson        return CC_LIKELY(currentTransform()->rectToRect());
89984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    }
90984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
91984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    // Save (layer)
92984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int getSaveCount() const { return mSaveCount; }
93984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int save(int flags);
94984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void restore();
95984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void restoreToCount(int saveCount);
96984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
97984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    // Save/Restore without side-effects
98984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int saveSnapshot(int flags);
99984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void restoreSnapshot();
100984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
101984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    // Matrix
102984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void getMatrix(SkMatrix* outMatrix) const;
103984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void translate(float dx, float dy, float dz = 0.0f);
104984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void rotate(float degrees);
105984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void scale(float sx, float sy);
106984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void skew(float sx, float sy);
107984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
108984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setMatrix(const SkMatrix& matrix);
109984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setMatrix(const Matrix4& matrix); // internal only convenience method
110984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void concatMatrix(const SkMatrix& matrix);
111984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void concatMatrix(const Matrix4& matrix); // internal only convenience method
112984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
113984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    // Clip
114984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); }
115984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); }
116984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
117984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool quickRejectConservative(float left, float top, float right, float bottom) const;
118984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
119984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
120984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool clipPath(const SkPath* path, SkRegion::Op op);
121984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool clipRegion(const SkRegion* region, SkRegion::Op op);
122984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
123984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool isCurrentClipSimple() const {
124984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson        return currentSnapshot()->clipRegion->isEmpty();
125984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    }
126984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
127984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /**
128984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Sets a "clipping outline", which is independent from the regular clip.
129984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Currently only supports rectangles or rounded rectangles; passing in a
130984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * more complicated outline fails silently. Replaces any previous clipping
131984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * outline.
132984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     */
133984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
134984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setClippingRoundRect(LinearAllocator& allocator,
135984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson            const Rect& rect, float radius, bool highPriority = true);
136984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
137984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /**
138984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * Returns true if drawing in the rectangle (left, top, right, bottom)
139984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * will be clipped out. Is conservative: might return false when subpixel-
140984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     * perfect tests would return true.
141984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson     */
142984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
143984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson            bool* clipRequired, bool* roundRectClipRequired, bool snapOut) const;
144984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
145984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setDirtyClip(bool opaque) { mDirtyClip = opaque; }
146984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool getDirtyClip() const { return mDirtyClip; }
147984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
148984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; }
149984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setEmpty(bool value) { mSnapshot->empty = value; }
150984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    void setInvisible(bool value) { mSnapshot->invisible = value; }
151984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
152984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline const mat4* currentTransform() const { return currentSnapshot()->transform; }
153984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline const Rect* currentClipRect() const { return currentSnapshot()->clipRect; }
154984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline Region* currentRegion() const { return currentSnapshot()->region; }
155984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline int currentFlags() const { return currentSnapshot()->flags; }
156984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    const Vector3& currentLightCenter() const { return currentSnapshot()->getRelativeLightCenter(); }
157984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline bool currentlyIgnored() const { return currentSnapshot()->isIgnored(); }
158984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); }
159984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); }
160984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int getWidth() { return mWidth; }
161984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int getHeight() { return mHeight; }
162984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
163984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline const Snapshot* currentSnapshot() const {
164e84a208317e0ed388fcdad1e6743c7849acb51b0Chris Craik        return mSnapshot != nullptr ? mSnapshot.get() : mFirstSnapshot.get();
165984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    }
166984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline Snapshot* writableSnapshot() { return mSnapshot.get(); }
167984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    inline const Snapshot* firstSnapshot() const { return mFirstSnapshot.get(); }
168984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
169984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudsonprivate:
170984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// No default constructor - must supply a CanvasStateClient (mCanvas).
171984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    CanvasState();
172984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
173984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// indicates that the clip has been changed since the last time it was consumed
174984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    bool mDirtyClip;
175984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
176984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Dimensions of the drawing surface
177984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int mWidth, mHeight;
178984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
179984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Number of saved states
180984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    int mSaveCount;
181984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
182984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Base state
183984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    sp<Snapshot> mFirstSnapshot;
184984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
185984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Host providing callbacks
186984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    CanvasStateClient& mCanvas;
187984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
188984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    /// Current state
189984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson    sp<Snapshot> mSnapshot;
190984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
191984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // class CanvasState
192984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
193984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // namespace uirenderer
194984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson}; // namespace android
195984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson
196984162fb7e4010b6e2908352dbff17ed47eecf06Tom Hudson#endif // ANDROID_HWUI_CANVAS_STATE_H
197