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