2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <utils/RefBase.h>
21 #include <utils/Looper.h>
23 #include <gui/SurfaceComposerClient.h>
30 * Transformation matrix for a sprite.
32 struct SpriteTransformationMatrix {
33 inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { }
34 inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) :
35 dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { }
42 inline bool operator== (const SpriteTransformationMatrix& other) {
43 return dsdx == other.dsdx
46 && dtdy == other.dtdy;
49 inline bool operator!= (const SpriteTransformationMatrix& other) {
50 return !(*this == other);
55 * Icon that a sprite displays, including its hotspot.
58 inline SpriteIcon() : hotSpotX(0), hotSpotY(0) { }
59 inline SpriteIcon(const SkBitmap& bitmap, float hotSpotX, float hotSpotY) :
60 bitmap(bitmap), hotSpotX(hotSpotX), hotSpotY(hotSpotY) { }
66 inline SpriteIcon copy() const {
68 bitmap.copyTo(&bitmapCopy, kN32_SkColorType);
69 return SpriteIcon(bitmapCopy, hotSpotX, hotSpotY);
78 inline bool isValid() const {
79 return !bitmap.isNull() && !bitmap.empty();
84 * A sprite is a simple graphical object that is displayed on-screen above other layers.
85 * The basic sprite class is an interface.
86 * The implementation is provided by the sprite controller.
88 class Sprite : public RefBase {
95 // The base layer for pointer sprites.
96 BASE_LAYER_POINTER = 0, // reserve space for 1 pointer
98 // The base layer for spot sprites.
99 BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots
102 /* Sets the bitmap that is drawn by the sprite.
103 * The sprite retains a copy of the bitmap for subsequent rendering. */
104 virtual void setIcon(const SpriteIcon& icon) = 0;
106 inline void clearIcon() {
107 setIcon(SpriteIcon());
110 /* Sets whether the sprite is visible. */
111 virtual void setVisible(bool visible) = 0;
113 /* Sets the sprite position on screen, relative to the sprite's hot spot. */
114 virtual void setPosition(float x, float y) = 0;
116 /* Sets the layer of the sprite, relative to the system sprite overlay layer.
117 * Layer 0 is the overlay layer, > 0 appear above this layer. */
118 virtual void setLayer(int32_t layer) = 0;
120 /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
121 virtual void setAlpha(float alpha) = 0;
123 /* Sets the sprite transformation matrix. */
124 virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
128 * Displays sprites on the screen.
130 * This interface is used by PointerController and SpotController to draw pointers or
131 * spot representations of fingers. It is not intended for general purpose use
132 * by other components.
134 * All sprite position updates and rendering is performed asynchronously.
136 * Clients are responsible for animating sprites by periodically updating their properties.
138 class SpriteController : public MessageHandler {
140 virtual ~SpriteController();
143 SpriteController(const sp<Looper>& looper, int32_t overlayLayer);
145 /* Creates a new sprite, initially invisible. */
146 sp<Sprite> createSprite();
148 /* Opens or closes a transaction to perform a batch of sprite updates as part of
149 * a single operation such as setPosition and setAlpha. It is not necessary to
150 * open a transaction when updating a single property.
151 * Calls to openTransaction() nest and must be matched by an equal number
152 * of calls to closeTransaction(). */
153 void openTransaction();
154 void closeTransaction();
159 MSG_DISPOSE_SURFACES,
163 DIRTY_BITMAP = 1 << 0,
164 DIRTY_ALPHA = 1 << 1,
165 DIRTY_POSITION = 1 << 2,
166 DIRTY_TRANSFORMATION_MATRIX = 1 << 3,
167 DIRTY_LAYER = 1 << 4,
168 DIRTY_VISIBILITY = 1 << 5,
169 DIRTY_HOTSPOT = 1 << 6,
172 /* Describes the state of a sprite.
173 * This structure is designed so that it can be copied during updates so that
174 * surfaces can be resized and redrawn without blocking the client by holding a lock
175 * on the sprites for a long time.
176 * Note that the SkBitmap holds a reference to a shared (and immutable) pixel ref. */
178 inline SpriteState() :
179 dirty(0), visible(false),
180 positionX(0), positionY(0), layer(0), alpha(1.0f),
181 surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
192 SpriteTransformationMatrix transformationMatrix;
194 sp<SurfaceControl> surfaceControl;
195 int32_t surfaceWidth;
196 int32_t surfaceHeight;
200 inline bool wantSurfaceVisible() const {
201 return visible && alpha > 0.0f && icon.isValid();
205 /* Client interface for a sprite.
206 * Requests acquire a lock on the controller, update local state and request the
207 * controller to invalidate the sprite.
208 * The real heavy lifting of creating, resizing and redrawing surfaces happens
209 * asynchronously with no locks held except in short critical section to copy
210 * the sprite state before the work and update the sprite surface control afterwards.
212 class SpriteImpl : public Sprite {
214 virtual ~SpriteImpl();
217 SpriteImpl(const sp<SpriteController> controller);
219 virtual void setIcon(const SpriteIcon& icon);
220 virtual void setVisible(bool visible);
221 virtual void setPosition(float x, float y);
222 virtual void setLayer(int32_t layer);
223 virtual void setAlpha(float alpha);
224 virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
226 inline const SpriteState& getStateLocked() const {
227 return mLocked.state;
230 inline void resetDirtyLocked() {
231 mLocked.state.dirty = 0;
234 inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl,
235 int32_t width, int32_t height, bool drawn, bool visible) {
236 mLocked.state.surfaceControl = surfaceControl;
237 mLocked.state.surfaceWidth = width;
238 mLocked.state.surfaceHeight = height;
239 mLocked.state.surfaceDrawn = drawn;
240 mLocked.state.surfaceVisible = visible;
244 sp<SpriteController> mController;
248 } mLocked; // guarded by mController->mLock
250 void invalidateLocked(uint32_t dirty);
253 /* Stores temporary information collected during the sprite update cycle. */
254 struct SpriteUpdate {
255 inline SpriteUpdate() : surfaceChanged(false) { }
256 inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) :
257 sprite(sprite), state(state), surfaceChanged(false) {
260 sp<SpriteImpl> sprite;
268 const int32_t mOverlayLayer;
269 sp<WeakMessageHandler> mHandler;
271 sp<SurfaceComposerClient> mSurfaceComposerClient;
274 Vector<sp<SpriteImpl> > invalidatedSprites;
275 Vector<sp<SurfaceControl> > disposedSurfaces;
276 uint32_t transactionNestingCount;
277 bool deferredSpriteUpdate;
278 } mLocked; // guarded by mLock
280 void invalidateSpriteLocked(const sp<SpriteImpl>& sprite);
281 void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl);
283 void handleMessage(const Message& message);
284 void doUpdateSprites();
285 void doDisposeSurfaces();
287 void ensureSurfaceComposerClient();
288 sp<SurfaceControl> obtainSurface(int32_t width, int32_t height);
291 } // namespace android
293 #endif // _UI_SPRITES_H