blob: 27afb5ecbd8240be167aa184d755fb9a77a21d1d [file] [log] [blame]
Jeff Brown5541de92011-04-11 11:54:25 -07001/*
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
29namespace android {
30
31/*
32 * Transformation matrix for a sprite.
33 */
34struct SpriteTransformationMatrix {
35 inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { }
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 */
59class Sprite : public RefBase {
60protected:
61 Sprite() { }
62 virtual ~Sprite() { }
63
64public:
65 /* Sets the bitmap that is drawn by the sprite.
66 * The sprite retains a copy of the bitmap for subsequent rendering. */
67 virtual void setBitmap(const SkBitmap* bitmap, float hotSpotX, float hotSpotY) = 0;
68
69 /* Sets whether the sprite is visible. */
70 virtual void setVisible(bool visible) = 0;
71
72 /* Sets the sprite position on screen, relative to the sprite's hot spot. */
73 virtual void setPosition(float x, float y) = 0;
74
75 /* Sets the layer of the sprite, relative to the system sprite overlay layer.
76 * Layer 0 is the overlay layer, > 0 appear above this layer. */
77 virtual void setLayer(int32_t layer) = 0;
78
79 /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
80 virtual void setAlpha(float alpha) = 0;
81
82 /* Sets the sprite transformation matrix. */
83 virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
84
85 /* Opens or closes a transaction to perform a batch of sprite updates as part of
86 * a single operation such as setPosition and setAlpha. It is not necessary to
87 * open a transaction when updating a single property.
88 * Calls to openTransaction() nest and must be matched by an equal number
89 * of calls to closeTransaction(). */
90 virtual void openTransaction() = 0;
91 virtual void closeTransaction() = 0;
92};
93
94/*
95 * Displays sprites on the screen.
96 *
97 * This interface is used by PointerController and SpotController to draw pointers or
98 * spot representations of fingers. It is not intended for general purpose use
99 * by other components.
100 *
101 * All sprite position updates and rendering is performed asynchronously.
102 *
103 * Clients are responsible for animating sprites by periodically updating their properties.
104 */
105class SpriteController : public MessageHandler {
106protected:
107 virtual ~SpriteController();
108
109public:
110 SpriteController(const sp<Looper>& looper, int32_t overlayLayer);
111
112 /* Creates a new sprite, initially invisible. */
113 sp<Sprite> createSprite();
114
115private:
116 enum {
117 MSG_UPDATE_SPRITES,
118 MSG_DISPOSE_SURFACES,
119 };
120
121 enum {
122 DIRTY_BITMAP = 1 << 0,
123 DIRTY_ALPHA = 1 << 1,
124 DIRTY_POSITION = 1 << 2,
125 DIRTY_TRANSFORMATION_MATRIX = 1 << 3,
126 DIRTY_LAYER = 1 << 4,
127 DIRTY_VISIBILITY = 1 << 5,
128 DIRTY_HOTSPOT = 1 << 6,
129 };
130
131 /* Describes the state of a sprite.
132 * This structure is designed so that it can be copied during updates so that
133 * surfaces can be resized and redrawn without blocking the client by holding a lock
134 * on the sprites for a long time.
135 * Note that the SkBitmap holds a reference to a shared (and immutable) pixel ref. */
136 struct SpriteState {
137 inline SpriteState() :
138 dirty(0), hotSpotX(0), hotSpotY(0), visible(false),
139 positionX(0), positionY(0), layer(0), alpha(1.0f),
140 surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
141 }
142
143 uint32_t dirty;
144
145 SkBitmap bitmap;
146 float hotSpotX;
147 float hotSpotY;
148 bool visible;
149 float positionX;
150 float positionY;
151 int32_t layer;
152 float alpha;
153 SpriteTransformationMatrix transformationMatrix;
154
155 sp<SurfaceControl> surfaceControl;
156 int32_t surfaceWidth;
157 int32_t surfaceHeight;
158 bool surfaceDrawn;
159 bool surfaceVisible;
160
161 inline bool wantSurfaceVisible() const {
162 return visible && alpha > 0.0f && !bitmap.isNull() && !bitmap.empty();
163 }
164 };
165
166 /* Client interface for a sprite.
167 * Requests acquire a lock on the controller, update local state and request the
168 * controller to invalidate the sprite.
169 * The real heavy lifting of creating, resizing and redrawing surfaces happens
170 * asynchronously with no locks held except in short critical section to copy
171 * the sprite state before the work and update the sprite surface control afterwards.
172 */
173 class SpriteImpl : public Sprite {
174 protected:
175 virtual ~SpriteImpl();
176
177 public:
178 SpriteImpl(const sp<SpriteController> controller);
179
180 virtual void setBitmap(const SkBitmap* bitmap, float hotSpotX, float hotSpotY);
181 virtual void setVisible(bool visible);
182 virtual void setPosition(float x, float y);
183 virtual void setLayer(int32_t layer);
184 virtual void setAlpha(float alpha);
185 virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
186 virtual void openTransaction();
187 virtual void closeTransaction();
188
189 inline const SpriteState& getStateLocked() const {
190 return mState;
191 }
192
193 inline void resetDirtyLocked() {
194 mState.dirty = 0;
195 }
196
197 inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl,
198 int32_t width, int32_t height, bool drawn, bool visible) {
199 mState.surfaceControl = surfaceControl;
200 mState.surfaceWidth = width;
201 mState.surfaceHeight = height;
202 mState.surfaceDrawn = drawn;
203 mState.surfaceVisible = visible;
204 }
205
206 private:
207 sp<SpriteController> mController;
208
209 SpriteState mState; // guarded by mController->mLock
210 uint32_t mTransactionNestingCount; // guarded by mController->mLock
211
212 void invalidateLocked(uint32_t dirty);
213 };
214
215 /* Stores temporary information collected during the sprite update cycle. */
216 struct SpriteUpdate {
217 inline SpriteUpdate() : surfaceChanged(false) { }
218 inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) :
219 sprite(sprite), state(state), surfaceChanged(false) {
220 }
221
222 sp<SpriteImpl> sprite;
223 SpriteState state;
224 bool surfaceChanged;
225 };
226
227 mutable Mutex mLock;
228
229 sp<Looper> mLooper;
230 const int32_t mOverlayLayer;
231 sp<WeakMessageHandler> mHandler;
232
233 sp<SurfaceComposerClient> mSurfaceComposerClient;
234
235 Vector<sp<SpriteImpl> > mInvalidatedSprites; // guarded by mLock
236 Vector<sp<SurfaceControl> > mDisposedSurfaces; // guarded by mLock
237
238 void invalidateSpriteLocked(const sp<SpriteImpl>& sprite);
239 void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl);
240
241 void handleMessage(const Message& message);
242 void doUpdateSprites();
243 void doDisposeSurfaces();
244
245 void ensureSurfaceComposerClient();
246 sp<SurfaceControl> obtainSurface(int32_t width, int32_t height);
247};
248
249} // namespace android
250
251#endif // _UI_SPRITES_H