• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <surfaceflinger/Surface.h>
24 #include <surfaceflinger/SurfaceComposerClient.h>
25 #include <surfaceflinger/ISurfaceComposer.h>
26 
27 #include <SkBitmap.h>
28 
29 namespace android {
30 
31 /*
32  * Transformation matrix for a sprite.
33  */
34 struct SpriteTransformationMatrix {
SpriteTransformationMatrixSpriteTransformationMatrix35     inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { }
SpriteTransformationMatrixSpriteTransformationMatrix36     inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) :
37             dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { }
38 
39     float dsdx;
40     float dtdx;
41     float dsdy;
42     float dtdy;
43 
44     inline bool operator== (const SpriteTransformationMatrix& other) {
45         return dsdx == other.dsdx
46                 && dtdx == other.dtdx
47                 && dsdy == other.dsdy
48                 && dtdy == other.dtdy;
49     }
50 
51     inline bool operator!= (const SpriteTransformationMatrix& other) {
52         return !(*this == other);
53     }
54 };
55 
56 /*
57  * Icon that a sprite displays, including its hotspot.
58  */
59 struct SpriteIcon {
SpriteIconSpriteIcon60     inline SpriteIcon() : hotSpotX(0), hotSpotY(0) { }
SpriteIconSpriteIcon61     inline SpriteIcon(const SkBitmap& bitmap, float hotSpotX, float hotSpotY) :
62             bitmap(bitmap), hotSpotX(hotSpotX), hotSpotY(hotSpotY) { }
63 
64     SkBitmap bitmap;
65     float hotSpotX;
66     float hotSpotY;
67 
copySpriteIcon68     inline SpriteIcon copy() const {
69         SkBitmap bitmapCopy;
70         bitmap.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config);
71         return SpriteIcon(bitmapCopy, hotSpotX, hotSpotY);
72     }
73 
resetSpriteIcon74     inline void reset() {
75         bitmap.reset();
76         hotSpotX = 0;
77         hotSpotY = 0;
78     }
79 
isValidSpriteIcon80     inline bool isValid() const {
81         return !bitmap.isNull() && !bitmap.empty();
82     }
83 };
84 
85 /*
86  * A sprite is a simple graphical object that is displayed on-screen above other layers.
87  * The basic sprite class is an interface.
88  * The implementation is provided by the sprite controller.
89  */
90 class Sprite : public RefBase {
91 protected:
Sprite()92     Sprite() { }
~Sprite()93     virtual ~Sprite() { }
94 
95 public:
96     enum {
97         // The base layer for pointer sprites.
98         BASE_LAYER_POINTER = 0, // reserve space for 1 pointer
99 
100         // The base layer for spot sprites.
101         BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots
102     };
103 
104     /* Sets the bitmap that is drawn by the sprite.
105      * The sprite retains a copy of the bitmap for subsequent rendering. */
106     virtual void setIcon(const SpriteIcon& icon) = 0;
107 
clearIcon()108     inline void clearIcon() {
109         setIcon(SpriteIcon());
110     }
111 
112     /* Sets whether the sprite is visible. */
113     virtual void setVisible(bool visible) = 0;
114 
115     /* Sets the sprite position on screen, relative to the sprite's hot spot. */
116     virtual void setPosition(float x, float y) = 0;
117 
118     /* Sets the layer of the sprite, relative to the system sprite overlay layer.
119      * Layer 0 is the overlay layer, > 0 appear above this layer. */
120     virtual void setLayer(int32_t layer) = 0;
121 
122     /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
123     virtual void setAlpha(float alpha) = 0;
124 
125     /* Sets the sprite transformation matrix. */
126     virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 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     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     void openTransaction();
156     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     };
173 
174     /* Describes the state of a sprite.
175      * This structure is designed so that it can be copied during updates so that
176      * surfaces can be resized and redrawn without blocking the client by holding a lock
177      * on the sprites for a long time.
178      * Note that the SkBitmap holds a reference to a shared (and immutable) pixel ref. */
179     struct SpriteState {
SpriteStateSpriteState180         inline SpriteState() :
181                 dirty(0), visible(false),
182                 positionX(0), positionY(0), layer(0), alpha(1.0f),
183                 surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
184         }
185 
186         uint32_t dirty;
187 
188         SpriteIcon icon;
189         bool visible;
190         float positionX;
191         float positionY;
192         int32_t layer;
193         float alpha;
194         SpriteTransformationMatrix transformationMatrix;
195 
196         sp<SurfaceControl> surfaceControl;
197         int32_t surfaceWidth;
198         int32_t surfaceHeight;
199         bool surfaceDrawn;
200         bool surfaceVisible;
201 
wantSurfaceVisibleSpriteState202         inline bool wantSurfaceVisible() const {
203             return visible && alpha > 0.0f && icon.isValid();
204         }
205     };
206 
207     /* Client interface for a sprite.
208      * Requests acquire a lock on the controller, update local state and request the
209      * controller to invalidate the sprite.
210      * The real heavy lifting of creating, resizing and redrawing surfaces happens
211      * asynchronously with no locks held except in short critical section to copy
212      * the sprite state before the work and update the sprite surface control afterwards.
213      */
214     class SpriteImpl : public Sprite {
215     protected:
216         virtual ~SpriteImpl();
217 
218     public:
219         SpriteImpl(const sp<SpriteController> controller);
220 
221         virtual void setIcon(const SpriteIcon& icon);
222         virtual void setVisible(bool visible);
223         virtual void setPosition(float x, float y);
224         virtual void setLayer(int32_t layer);
225         virtual void setAlpha(float alpha);
226         virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
227 
getStateLocked()228         inline const SpriteState& getStateLocked() const {
229             return mLocked.state;
230         }
231 
resetDirtyLocked()232         inline void resetDirtyLocked() {
233             mLocked.state.dirty = 0;
234         }
235 
setSurfaceLocked(const sp<SurfaceControl> & surfaceControl,int32_t width,int32_t height,bool drawn,bool visible)236         inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl,
237                 int32_t width, int32_t height, bool drawn, bool visible) {
238             mLocked.state.surfaceControl = surfaceControl;
239             mLocked.state.surfaceWidth = width;
240             mLocked.state.surfaceHeight = height;
241             mLocked.state.surfaceDrawn = drawn;
242             mLocked.state.surfaceVisible = visible;
243         }
244 
245     private:
246         sp<SpriteController> mController;
247 
248         struct Locked {
249             SpriteState state;
250         } mLocked; // guarded by mController->mLock
251 
252         void invalidateLocked(uint32_t dirty);
253     };
254 
255     /* Stores temporary information collected during the sprite update cycle. */
256     struct SpriteUpdate {
SpriteUpdateSpriteUpdate257         inline SpriteUpdate() : surfaceChanged(false) { }
SpriteUpdateSpriteUpdate258         inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) :
259                 sprite(sprite), state(state), surfaceChanged(false) {
260         }
261 
262         sp<SpriteImpl> sprite;
263         SpriteState state;
264         bool surfaceChanged;
265     };
266 
267     mutable Mutex mLock;
268 
269     sp<Looper> mLooper;
270     const int32_t mOverlayLayer;
271     sp<WeakMessageHandler> mHandler;
272 
273     sp<SurfaceComposerClient> mSurfaceComposerClient;
274 
275     struct Locked {
276         Vector<sp<SpriteImpl> > invalidatedSprites;
277         Vector<sp<SurfaceControl> > disposedSurfaces;
278         uint32_t transactionNestingCount;
279         bool deferredSpriteUpdate;
280     } mLocked; // guarded by mLock
281 
282     void invalidateSpriteLocked(const sp<SpriteImpl>& sprite);
283     void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl);
284 
285     void handleMessage(const Message& message);
286     void doUpdateSprites();
287     void doDisposeSurfaces();
288 
289     void ensureSurfaceComposerClient();
290     sp<SurfaceControl> obtainSurface(int32_t width, int32_t height);
291 };
292 
293 } // namespace android
294 
295 #endif // _UI_SPRITES_H
296