Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
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 */
17 #ifndef _UI_SPRITES_H
18 #define _UI_SPRITES_H
20 #include <utils/RefBase.h>
21 #include <utils/Looper.h>
23 #ifdef HAVE_ANDROID_OS
24 #include <gui/SurfaceComposerClient.h>
25 #endif
27 #include <SkBitmap.h>
29 namespace android {
31 /*
32 * Transformation matrix for a sprite.
33 */
34 struct SpriteTransformationMatrix {
35 inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { }
36 inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) :
37 dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { }
39 float dsdx;
40 float dtdx;
41 float dsdy;
42 float dtdy;
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 }
51 inline bool operator!= (const SpriteTransformationMatrix& other) {
52 return !(*this == other);
53 }
54 };
56 /*
57 * Icon that a sprite displays, including its hotspot.
58 */
59 struct SpriteIcon {
60 inline SpriteIcon() : hotSpotX(0), hotSpotY(0) { }
61 #ifdef HAVE_ANDROID_OS
62 inline SpriteIcon(const SkBitmap& bitmap, float hotSpotX, float hotSpotY) :
63 bitmap(bitmap), hotSpotX(hotSpotX), hotSpotY(hotSpotY) { }
65 SkBitmap bitmap;
66 #endif
67 float hotSpotX;
68 float hotSpotY;
70 inline SpriteIcon copy() const {
71 #ifdef HAVE_ANDROID_OS
72 SkBitmap bitmapCopy;
73 bitmap.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config);
74 return SpriteIcon(bitmapCopy, hotSpotX, hotSpotY);
75 #else
76 return SpriteIcon();
77 #endif
78 }
80 inline void reset() {
81 #ifdef HAVE_ANDROID_OS
82 bitmap.reset();
83 hotSpotX = 0;
84 hotSpotY = 0;
85 #endif
86 }
88 inline bool isValid() const {
89 #ifdef HAVE_ANDROID_OS
90 return !bitmap.isNull() && !bitmap.empty();
91 #else
92 return false;
93 #endif
94 }
95 };
97 /*
98 * A sprite is a simple graphical object that is displayed on-screen above other layers.
99 * The basic sprite class is an interface.
100 * The implementation is provided by the sprite controller.
101 */
102 class Sprite : public RefBase {
103 protected:
104 Sprite() { }
105 virtual ~Sprite() { }
107 public:
108 enum {
109 // The base layer for pointer sprites.
110 BASE_LAYER_POINTER = 0, // reserve space for 1 pointer
112 // The base layer for spot sprites.
113 BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots
114 };
116 /* Sets the bitmap that is drawn by the sprite.
117 * The sprite retains a copy of the bitmap for subsequent rendering. */
118 virtual void setIcon(const SpriteIcon& icon) = 0;
120 inline void clearIcon() {
121 setIcon(SpriteIcon());
122 }
124 /* Sets whether the sprite is visible. */
125 virtual void setVisible(bool visible) = 0;
127 /* Sets the sprite position on screen, relative to the sprite's hot spot. */
128 virtual void setPosition(float x, float y) = 0;
130 /* Sets the layer of the sprite, relative to the system sprite overlay layer.
131 * Layer 0 is the overlay layer, > 0 appear above this layer. */
132 virtual void setLayer(int32_t layer) = 0;
134 /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
135 virtual void setAlpha(float alpha) = 0;
137 /* Sets the sprite transformation matrix. */
138 virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
139 };
141 /*
142 * Displays sprites on the screen.
143 *
144 * This interface is used by PointerController and SpotController to draw pointers or
145 * spot representations of fingers. It is not intended for general purpose use
146 * by other components.
147 *
148 * All sprite position updates and rendering is performed asynchronously.
149 *
150 * Clients are responsible for animating sprites by periodically updating their properties.
151 */
152 class SpriteController : public MessageHandler {
153 protected:
154 virtual ~SpriteController();
156 public:
157 SpriteController(const sp<Looper>& looper, int32_t overlayLayer);
159 /* Creates a new sprite, initially invisible. */
160 sp<Sprite> createSprite();
162 /* Opens or closes a transaction to perform a batch of sprite updates as part of
163 * a single operation such as setPosition and setAlpha. It is not necessary to
164 * open a transaction when updating a single property.
165 * Calls to openTransaction() nest and must be matched by an equal number
166 * of calls to closeTransaction(). */
167 void openTransaction();
168 void closeTransaction();
170 private:
171 enum {
172 MSG_UPDATE_SPRITES,
173 MSG_DISPOSE_SURFACES,
174 };
176 enum {
177 DIRTY_BITMAP = 1 << 0,
178 DIRTY_ALPHA = 1 << 1,
179 DIRTY_POSITION = 1 << 2,
180 DIRTY_TRANSFORMATION_MATRIX = 1 << 3,
181 DIRTY_LAYER = 1 << 4,
182 DIRTY_VISIBILITY = 1 << 5,
183 DIRTY_HOTSPOT = 1 << 6,
184 };
186 /* Describes the state of a sprite.
187 * This structure is designed so that it can be copied during updates so that
188 * surfaces can be resized and redrawn without blocking the client by holding a lock
189 * on the sprites for a long time.
190 * Note that the SkBitmap holds a reference to a shared (and immutable) pixel ref. */
191 struct SpriteState {
192 inline SpriteState() :
193 dirty(0), visible(false),
194 positionX(0), positionY(0), layer(0), alpha(1.0f),
195 surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
196 }
198 uint32_t dirty;
200 SpriteIcon icon;
201 bool visible;
202 float positionX;
203 float positionY;
204 int32_t layer;
205 float alpha;
206 SpriteTransformationMatrix transformationMatrix;
208 #ifdef HAVE_ANDROID_OS
209 sp<SurfaceControl> surfaceControl;
210 #endif
211 int32_t surfaceWidth;
212 int32_t surfaceHeight;
213 bool surfaceDrawn;
214 bool surfaceVisible;
216 inline bool wantSurfaceVisible() const {
217 return visible && alpha > 0.0f && icon.isValid();
218 }
219 };
221 /* Client interface for a sprite.
222 * Requests acquire a lock on the controller, update local state and request the
223 * controller to invalidate the sprite.
224 * The real heavy lifting of creating, resizing and redrawing surfaces happens
225 * asynchronously with no locks held except in short critical section to copy
226 * the sprite state before the work and update the sprite surface control afterwards.
227 */
228 class SpriteImpl : public Sprite {
229 protected:
230 virtual ~SpriteImpl();
232 public:
233 SpriteImpl(const sp<SpriteController> controller);
235 virtual void setIcon(const SpriteIcon& icon);
236 virtual void setVisible(bool visible);
237 virtual void setPosition(float x, float y);
238 virtual void setLayer(int32_t layer);
239 virtual void setAlpha(float alpha);
240 virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
242 inline const SpriteState& getStateLocked() const {
243 return mLocked.state;
244 }
246 inline void resetDirtyLocked() {
247 mLocked.state.dirty = 0;
248 }
250 #ifdef HAVE_ANDROID_OS
251 inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl,
252 int32_t width, int32_t height, bool drawn, bool visible) {
253 mLocked.state.surfaceControl = surfaceControl;
254 mLocked.state.surfaceWidth = width;
255 mLocked.state.surfaceHeight = height;
256 mLocked.state.surfaceDrawn = drawn;
257 mLocked.state.surfaceVisible = visible;
258 }
259 #endif
261 private:
262 sp<SpriteController> mController;
264 struct Locked {
265 SpriteState state;
266 } mLocked; // guarded by mController->mLock
268 void invalidateLocked(uint32_t dirty);
269 };
271 /* Stores temporary information collected during the sprite update cycle. */
272 struct SpriteUpdate {
273 inline SpriteUpdate() : surfaceChanged(false) { }
274 inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) :
275 sprite(sprite), state(state), surfaceChanged(false) {
276 }
278 sp<SpriteImpl> sprite;
279 SpriteState state;
280 bool surfaceChanged;
281 };
283 mutable Mutex mLock;
285 sp<Looper> mLooper;
286 const int32_t mOverlayLayer;
287 #ifdef HAVE_ANDROID_OS
288 sp<WeakMessageHandler> mHandler;
290 sp<SurfaceComposerClient> mSurfaceComposerClient;
291 #endif
293 struct Locked {
294 Vector<sp<SpriteImpl> > invalidatedSprites;
295 #ifdef HAVE_ANDROID_OS
296 Vector<sp<SurfaceControl> > disposedSurfaces;
297 #endif
298 uint32_t transactionNestingCount;
299 bool deferredSpriteUpdate;
300 } mLocked; // guarded by mLock
302 void invalidateSpriteLocked(const sp<SpriteImpl>& sprite);
303 #ifdef HAVE_ANDROID_OS
304 void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl);
306 void handleMessage(const Message& message);
307 #endif
308 void doUpdateSprites();
309 void doDisposeSurfaces();
311 void ensureSurfaceComposerClient();
312 #ifdef HAVE_ANDROID_OS
313 sp<SurfaceControl> obtainSurface(int32_t width, int32_t height);
314 #endif
315 };
317 } // namespace android
319 #endif // _UI_SPRITES_H