1 /*
2  * Copyright (C) 2011 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 _UI_SPRITES_H
18 #define _UI_SPRITES_H
19 
20 #include <utils/RefBase.h>
21 #include <utils/Looper.h>
22 
23 #include <gui/SurfaceComposerClient.h>
24 
25 #include "SpriteIcon.h"
26 
27 namespace android {
28 
29 /*
30  * Transformation matrix for a sprite.
31  */
32 struct SpriteTransformationMatrix {
SpriteTransformationMatrixSpriteTransformationMatrix33     inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { }
SpriteTransformationMatrixSpriteTransformationMatrix34     inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) :
35             dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { }
36 
37     float dsdx;
38     float dtdx;
39     float dsdy;
40     float dtdy;
41 
42     inline bool operator== (const SpriteTransformationMatrix& other) {
43         return dsdx == other.dsdx
44                 && dtdx == other.dtdx
45                 && dsdy == other.dsdy
46                 && dtdy == other.dtdy;
47     }
48 
49     inline bool operator!= (const SpriteTransformationMatrix& other) {
50         return !(*this == other);
51     }
52 };
53 
54 /*
55  * A sprite is a simple graphical object that is displayed on-screen above other layers.
56  * The basic sprite class is an interface.
57  * The implementation is provided by the sprite controller.
58  */
59 class Sprite : public RefBase {
60 protected:
Sprite()61     Sprite() { }
~Sprite()62     virtual ~Sprite() { }
63 
64 public:
65     enum {
66         // The base layer for pointer sprites.
67         BASE_LAYER_POINTER = 0, // reserve space for 1 pointer
68 
69         // The base layer for spot sprites.
70         BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots
71     };
72 
73     /* Sets the bitmap that is drawn by the sprite.
74      * The sprite retains a copy of the bitmap for subsequent rendering. */
75     virtual void setIcon(const SpriteIcon& icon) = 0;
76 
clearIcon()77     inline void clearIcon() {
78         setIcon(SpriteIcon());
79     }
80 
81     /* Sets whether the sprite is visible. */
82     virtual void setVisible(bool visible) = 0;
83 
84     /* Sets the sprite position on screen, relative to the sprite's hot spot. */
85     virtual void setPosition(float x, float y) = 0;
86 
87     /* Sets the layer of the sprite, relative to the system sprite overlay layer.
88      * Layer 0 is the overlay layer, > 0 appear above this layer. */
89     virtual void setLayer(int32_t layer) = 0;
90 
91     /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
92     virtual void setAlpha(float alpha) = 0;
93 
94     /* Sets the sprite transformation matrix. */
95     virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
96 
97     /* Sets the id of the display where the sprite should be shown. */
98     virtual void setDisplayId(ui::LogicalDisplayId displayId) = 0;
99 
100     /* Sets the flag to hide sprite on mirrored displays.
101      * This will add ISurfaceComposerClient::eSkipScreenshot flag to the sprite. */
102     virtual void setSkipScreenshot(bool skip) = 0;
103 };
104 
105 /*
106  * Displays sprites on the screen.
107  *
108  * This interface is used by PointerController and SpotController to draw pointers or
109  * spot representations of fingers.  It is not intended for general purpose use
110  * by other components.
111  *
112  * All sprite position updates and rendering is performed asynchronously.
113  *
114  * Clients are responsible for animating sprites by periodically updating their properties.
115  */
116 class SpriteController {
117 public:
118     using ParentSurfaceProvider = std::function<sp<SurfaceControl>(ui::LogicalDisplayId)>;
119     SpriteController(const sp<Looper>& looper, int32_t overlayLayer, ParentSurfaceProvider parent);
120     SpriteController(const SpriteController&) = delete;
121     SpriteController& operator=(const SpriteController&) = delete;
122     virtual ~SpriteController();
123 
124     /* Initialize the callback for the message handler. */
125     void setHandlerController(const std::shared_ptr<SpriteController>& controller);
126 
127     /* Creates a new sprite, initially invisible. The lifecycle of the sprite must not extend beyond
128      * the lifecycle of this SpriteController. */
129     virtual sp<Sprite> createSprite();
130 
131     /* Opens or closes a transaction to perform a batch of sprite updates as part of
132      * a single operation such as setPosition and setAlpha.  It is not necessary to
133      * open a transaction when updating a single property.
134      * Calls to openTransaction() nest and must be matched by an equal number
135      * of calls to closeTransaction(). */
136     virtual void openTransaction();
137     virtual void closeTransaction();
138 
139 private:
140     class Handler : public virtual android::MessageHandler {
141     public:
142         enum { MSG_UPDATE_SPRITES, MSG_DISPOSE_SURFACES };
143 
144         void handleMessage(const Message& message) override;
145         std::weak_ptr<SpriteController> spriteController;
146     };
147 
148     enum {
149         DIRTY_BITMAP = 1 << 0,
150         DIRTY_ALPHA = 1 << 1,
151         DIRTY_POSITION = 1 << 2,
152         DIRTY_TRANSFORMATION_MATRIX = 1 << 3,
153         DIRTY_LAYER = 1 << 4,
154         DIRTY_VISIBILITY = 1 << 5,
155         DIRTY_HOTSPOT = 1 << 6,
156         DIRTY_DISPLAY_ID = 1 << 7,
157         DIRTY_ICON_STYLE = 1 << 8,
158         DIRTY_DRAW_DROP_SHADOW = 1 << 9,
159         DIRTY_SKIP_SCREENSHOT = 1 << 10,
160     };
161 
162     /* Describes the state of a sprite.
163      * This structure is designed so that it can be copied during updates so that
164      * surfaces can be resized and redrawn without blocking the client by holding a lock
165      * on the sprites for a long time.
166      * Note that the SpriteIcon holds a reference to a shared (and immutable) bitmap. */
167     struct SpriteState {
168         uint32_t dirty{0};
169 
170         SpriteIcon icon;
171         bool visible{false};
172         float positionX{0};
173         float positionY{0};
174         int32_t layer{0};
175         float alpha{1.0f};
176         SpriteTransformationMatrix transformationMatrix;
177         ui::LogicalDisplayId displayId{ui::LogicalDisplayId::DEFAULT};
178 
179         sp<SurfaceControl> surfaceControl;
180         int32_t surfaceWidth{0};
181         int32_t surfaceHeight{0};
182         bool surfaceDrawn{false};
183         bool surfaceVisible{false};
184         bool skipScreenshot{false};
185 
wantSurfaceVisibleSpriteState186         inline bool wantSurfaceVisible() const {
187             return visible && alpha > 0.0f && icon.isValid();
188         }
189     };
190 
191     /* Client interface for a sprite.
192      * Requests acquire a lock on the controller, update local state and request the
193      * controller to invalidate the sprite.
194      * The real heavy lifting of creating, resizing and redrawing surfaces happens
195      * asynchronously with no locks held except in short critical section to copy
196      * the sprite state before the work and update the sprite surface control afterwards.
197      */
198     class SpriteImpl : public Sprite {
199     protected:
200         virtual ~SpriteImpl();
201 
202     public:
203         explicit SpriteImpl(SpriteController& controller);
204 
205         virtual void setIcon(const SpriteIcon& icon);
206         virtual void setVisible(bool visible);
207         virtual void setPosition(float x, float y);
208         virtual void setLayer(int32_t layer);
209         virtual void setAlpha(float alpha);
210         virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
211         virtual void setDisplayId(ui::LogicalDisplayId displayId);
212         virtual void setSkipScreenshot(bool skip);
213 
getStateLocked()214         inline const SpriteState& getStateLocked() const {
215             return mLocked.state;
216         }
217 
resetDirtyLocked()218         inline void resetDirtyLocked() {
219             mLocked.state.dirty = 0;
220         }
221 
setSurfaceLocked(const sp<SurfaceControl> & surfaceControl,int32_t width,int32_t height,bool drawn,bool visible)222         inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl,
223                 int32_t width, int32_t height, bool drawn, bool visible) {
224             mLocked.state.surfaceControl = surfaceControl;
225             mLocked.state.surfaceWidth = width;
226             mLocked.state.surfaceHeight = height;
227             mLocked.state.surfaceDrawn = drawn;
228             mLocked.state.surfaceVisible = visible;
229         }
230 
231     private:
232         SpriteController& mController;
233 
234         struct Locked {
235             SpriteState state;
236         } mLocked; // guarded by mController->mLock
237 
238         void invalidateLocked(uint32_t dirty);
239     };
240 
241     /* Stores temporary information collected during the sprite update cycle. */
242     struct SpriteUpdate {
SpriteUpdateSpriteUpdate243         inline SpriteUpdate() : surfaceChanged(false) { }
SpriteUpdateSpriteUpdate244         inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) :
245                 sprite(sprite), state(state), surfaceChanged(false) {
246         }
247 
248         sp<SpriteImpl> sprite;
249         SpriteState state;
250         bool surfaceChanged;
251     };
252 
253     mutable Mutex mLock;
254 
255     sp<Looper> mLooper;
256     const int32_t mOverlayLayer;
257     sp<Handler> mHandler;
258     ParentSurfaceProvider mParentSurfaceProvider;
259 
260     sp<SurfaceComposerClient> mSurfaceComposerClient;
261 
262     struct Locked {
263         std::vector<sp<SpriteImpl>> invalidatedSprites;
264         std::vector<sp<SurfaceControl>> disposedSurfaces;
265         uint32_t transactionNestingCount;
266         bool deferredSpriteUpdate;
267     } mLocked; // guarded by mLock
268 
269     void invalidateSpriteLocked(const sp<SpriteImpl>& sprite);
270     void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl);
271 
272     void doUpdateSprites();
273     void doDisposeSurfaces();
274 
275     void ensureSurfaceComposerClient();
276     sp<SurfaceControl> obtainSurface(int32_t width, int32_t height, ui::LogicalDisplayId displayId,
277                                      bool hideOnMirrored);
278 };
279 
280 } // namespace android
281 
282 #endif // _UI_SPRITES_H
283