blob: e147c567ae2ddbf1012b90ebf77b71d3ceb029a0 [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
Mathias Agopian8335f1c2012-02-25 18:48:35 -080023#include <gui/SurfaceComposerClient.h>
Jeff Brown5541de92011-04-11 11:54:25 -070024
Garfield Tan7e3457e2020-05-28 14:31:29 -070025#include "SpriteIcon.h"
26
Jeff Brown5541de92011-04-11 11:54:25 -070027namespace android {
28
29/*
30 * Transformation matrix for a sprite.
31 */
32struct SpriteTransformationMatrix {
33 inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { }
Jeff Brown2352b972011-04-12 22:39:53 -070034 inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) :
35 dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { }
Jeff Brown5541de92011-04-11 11:54:25 -070036
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:
Jeff Brown2352b972011-04-12 22:39:53 -070065 enum {
66 // The base layer for pointer sprites.
67 BASE_LAYER_POINTER = 0, // reserve space for 1 pointer
68
69 // The base layer for spot sprites.
70 BASE_LAYER_SPOT = 1, // reserve space for MAX_POINTER_ID spots
71 };
72
Jeff Brown5541de92011-04-11 11:54:25 -070073 /* Sets the bitmap that is drawn by the sprite.
74 * The sprite retains a copy of the bitmap for subsequent rendering. */
Jeff Brown2352b972011-04-12 22:39:53 -070075 virtual void setIcon(const SpriteIcon& icon) = 0;
76
77 inline void clearIcon() {
78 setIcon(SpriteIcon());
79 }
Jeff Brown5541de92011-04-11 11:54:25 -070080
81 /* Sets whether the sprite is visible. */
82 virtual void setVisible(bool visible) = 0;
83
84 /* Sets the sprite position on screen, relative to the sprite's hot spot. */
85 virtual void setPosition(float x, float y) = 0;
86
87 /* Sets the layer of the sprite, relative to the system sprite overlay layer.
88 * Layer 0 is the overlay layer, > 0 appear above this layer. */
89 virtual void setLayer(int32_t layer) = 0;
90
91 /* Sets the sprite alpha blend ratio between 0.0 and 1.0. */
92 virtual void setAlpha(float alpha) = 0;
93
94 /* Sets the sprite transformation matrix. */
95 virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix) = 0;
Arthur Hungb9b32002018-12-18 17:39:43 +080096
97 /* Sets the id of the display where the sprite should be shown. */
Linnan Li0defadf2024-05-05 19:17:05 +080098 virtual void setDisplayId(ui::LogicalDisplayId displayId) = 0;
Arpit Singh80fd68a2024-03-26 18:41:06 +000099
100 /* Sets the flag to hide sprite on mirrored displays.
101 * This will add ISurfaceComposerClient::eSkipScreenshot flag to the sprite. */
102 virtual void setSkipScreenshot(bool skip) = 0;
Jeff Brown5541de92011-04-11 11:54:25 -0700103};
104
105/*
106 * Displays sprites on the screen.
107 *
108 * This interface is used by PointerController and SpotController to draw pointers or
109 * spot representations of fingers. It is not intended for general purpose use
110 * by other components.
111 *
112 * All sprite position updates and rendering is performed asynchronously.
113 *
114 * Clients are responsible for animating sprites by periodically updating their properties.
115 */
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000116class SpriteController {
Jeff Brown5541de92011-04-11 11:54:25 -0700117public:
Linnan Li0defadf2024-05-05 19:17:05 +0800118 using ParentSurfaceProvider = std::function<sp<SurfaceControl>(ui::LogicalDisplayId)>;
Prabir Pradhanfef0c612021-11-04 14:08:50 -0700119 SpriteController(const sp<Looper>& looper, int32_t overlayLayer, ParentSurfaceProvider parent);
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000120 SpriteController(const SpriteController&) = delete;
121 SpriteController& operator=(const SpriteController&) = delete;
122 virtual ~SpriteController();
Jeff Brown5541de92011-04-11 11:54:25 -0700123
Prabir Pradhan4cc1a632023-06-09 21:31:26 +0000124 /* Initialize the callback for the message handler. */
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000125 void setHandlerController(const std::shared_ptr<SpriteController>& controller);
Prabir Pradhan4cc1a632023-06-09 21:31:26 +0000126
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000127 /* Creates a new sprite, initially invisible. The lifecycle of the sprite must not extend beyond
128 * the lifecycle of this SpriteController. */
Garfield Tan67e479a2019-08-05 16:47:40 -0700129 virtual sp<Sprite> createSprite();
Jeff Brown5541de92011-04-11 11:54:25 -0700130
Jeff Brown2352b972011-04-12 22:39:53 -0700131 /* Opens or closes a transaction to perform a batch of sprite updates as part of
132 * a single operation such as setPosition and setAlpha. It is not necessary to
133 * open a transaction when updating a single property.
134 * Calls to openTransaction() nest and must be matched by an equal number
135 * of calls to closeTransaction(). */
Garfield Tan67e479a2019-08-05 16:47:40 -0700136 virtual void openTransaction();
137 virtual void closeTransaction();
Jeff Brown2352b972011-04-12 22:39:53 -0700138
Jeff Brown5541de92011-04-11 11:54:25 -0700139private:
Prabir Pradhan4cc1a632023-06-09 21:31:26 +0000140 class Handler : public virtual android::MessageHandler {
141 public:
142 enum { MSG_UPDATE_SPRITES, MSG_DISPOSE_SURFACES };
143
144 void handleMessage(const Message& message) override;
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000145 std::weak_ptr<SpriteController> spriteController;
Jeff Brown5541de92011-04-11 11:54:25 -0700146 };
147
148 enum {
149 DIRTY_BITMAP = 1 << 0,
150 DIRTY_ALPHA = 1 << 1,
151 DIRTY_POSITION = 1 << 2,
152 DIRTY_TRANSFORMATION_MATRIX = 1 << 3,
153 DIRTY_LAYER = 1 << 4,
154 DIRTY_VISIBILITY = 1 << 5,
155 DIRTY_HOTSPOT = 1 << 6,
Arthur Hungb9b32002018-12-18 17:39:43 +0800156 DIRTY_DISPLAY_ID = 1 << 7,
Garfield Tan67e479a2019-08-05 16:47:40 -0700157 DIRTY_ICON_STYLE = 1 << 8,
Pat Manningacbe18d2024-03-05 17:54:30 +0000158 DIRTY_DRAW_DROP_SHADOW = 1 << 9,
Arpit Singh80fd68a2024-03-26 18:41:06 +0000159 DIRTY_SKIP_SCREENSHOT = 1 << 10,
Jeff Brown5541de92011-04-11 11:54:25 -0700160 };
161
162 /* Describes the state of a sprite.
163 * This structure is designed so that it can be copied during updates so that
164 * surfaces can be resized and redrawn without blocking the client by holding a lock
165 * on the sprites for a long time.
Derek Sollenberger9ca5bbe2019-08-14 15:50:59 -0400166 * Note that the SpriteIcon holds a reference to a shared (and immutable) bitmap. */
Jeff Brown5541de92011-04-11 11:54:25 -0700167 struct SpriteState {
Arpit Singh81798022024-05-08 13:21:37 +0000168 uint32_t dirty{0};
Jeff Brown5541de92011-04-11 11:54:25 -0700169
Jeff Brown2352b972011-04-12 22:39:53 -0700170 SpriteIcon icon;
Arpit Singh81798022024-05-08 13:21:37 +0000171 bool visible{false};
172 float positionX{0};
173 float positionY{0};
174 int32_t layer{0};
175 float alpha{1.0f};
Jeff Brown5541de92011-04-11 11:54:25 -0700176 SpriteTransformationMatrix transformationMatrix;
Siarhei Vishniakou445af182024-05-13 13:17:05 -0700177 ui::LogicalDisplayId displayId{ui::LogicalDisplayId::DEFAULT};
Jeff Brown5541de92011-04-11 11:54:25 -0700178
179 sp<SurfaceControl> surfaceControl;
Arpit Singh81798022024-05-08 13:21:37 +0000180 int32_t surfaceWidth{0};
181 int32_t surfaceHeight{0};
182 bool surfaceDrawn{false};
183 bool surfaceVisible{false};
184 bool skipScreenshot{false};
Jeff Brown5541de92011-04-11 11:54:25 -0700185
186 inline bool wantSurfaceVisible() const {
Jeff Brown2352b972011-04-12 22:39:53 -0700187 return visible && alpha > 0.0f && icon.isValid();
Jeff Brown5541de92011-04-11 11:54:25 -0700188 }
189 };
190
191 /* Client interface for a sprite.
192 * Requests acquire a lock on the controller, update local state and request the
193 * controller to invalidate the sprite.
194 * The real heavy lifting of creating, resizing and redrawing surfaces happens
195 * asynchronously with no locks held except in short critical section to copy
196 * the sprite state before the work and update the sprite surface control afterwards.
197 */
198 class SpriteImpl : public Sprite {
199 protected:
200 virtual ~SpriteImpl();
201
202 public:
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000203 explicit SpriteImpl(SpriteController& controller);
Jeff Brown5541de92011-04-11 11:54:25 -0700204
Jeff Brown2352b972011-04-12 22:39:53 -0700205 virtual void setIcon(const SpriteIcon& icon);
Jeff Brown5541de92011-04-11 11:54:25 -0700206 virtual void setVisible(bool visible);
207 virtual void setPosition(float x, float y);
208 virtual void setLayer(int32_t layer);
209 virtual void setAlpha(float alpha);
210 virtual void setTransformationMatrix(const SpriteTransformationMatrix& matrix);
Linnan Li0defadf2024-05-05 19:17:05 +0800211 virtual void setDisplayId(ui::LogicalDisplayId displayId);
Arpit Singh80fd68a2024-03-26 18:41:06 +0000212 virtual void setSkipScreenshot(bool skip);
Jeff Brown5541de92011-04-11 11:54:25 -0700213
214 inline const SpriteState& getStateLocked() const {
Jeff Brown2352b972011-04-12 22:39:53 -0700215 return mLocked.state;
Jeff Brown5541de92011-04-11 11:54:25 -0700216 }
217
218 inline void resetDirtyLocked() {
Jeff Brown2352b972011-04-12 22:39:53 -0700219 mLocked.state.dirty = 0;
Jeff Brown5541de92011-04-11 11:54:25 -0700220 }
221
222 inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl,
223 int32_t width, int32_t height, bool drawn, bool visible) {
Jeff Brown2352b972011-04-12 22:39:53 -0700224 mLocked.state.surfaceControl = surfaceControl;
225 mLocked.state.surfaceWidth = width;
226 mLocked.state.surfaceHeight = height;
227 mLocked.state.surfaceDrawn = drawn;
228 mLocked.state.surfaceVisible = visible;
Jeff Brown5541de92011-04-11 11:54:25 -0700229 }
230
231 private:
Prabir Pradhan27c6d992023-08-18 19:44:55 +0000232 SpriteController& mController;
Jeff Brown5541de92011-04-11 11:54:25 -0700233
Jeff Brown2352b972011-04-12 22:39:53 -0700234 struct Locked {
235 SpriteState state;
236 } mLocked; // guarded by mController->mLock
Jeff Brown5541de92011-04-11 11:54:25 -0700237
238 void invalidateLocked(uint32_t dirty);
239 };
240
241 /* Stores temporary information collected during the sprite update cycle. */
242 struct SpriteUpdate {
243 inline SpriteUpdate() : surfaceChanged(false) { }
244 inline SpriteUpdate(const sp<SpriteImpl> sprite, const SpriteState& state) :
245 sprite(sprite), state(state), surfaceChanged(false) {
246 }
247
248 sp<SpriteImpl> sprite;
249 SpriteState state;
250 bool surfaceChanged;
251 };
252
253 mutable Mutex mLock;
254
255 sp<Looper> mLooper;
256 const int32_t mOverlayLayer;
Prabir Pradhan4cc1a632023-06-09 21:31:26 +0000257 sp<Handler> mHandler;
Prabir Pradhanfef0c612021-11-04 14:08:50 -0700258 ParentSurfaceProvider mParentSurfaceProvider;
Jeff Brown5541de92011-04-11 11:54:25 -0700259
260 sp<SurfaceComposerClient> mSurfaceComposerClient;
261
Jeff Brown2352b972011-04-12 22:39:53 -0700262 struct Locked {
Prabir Pradhan3f8b2892021-11-18 08:55:02 -0800263 std::vector<sp<SpriteImpl>> invalidatedSprites;
264 std::vector<sp<SurfaceControl>> disposedSurfaces;
Jeff Brown2352b972011-04-12 22:39:53 -0700265 uint32_t transactionNestingCount;
266 bool deferredSpriteUpdate;
267 } mLocked; // guarded by mLock
Jeff Brown5541de92011-04-11 11:54:25 -0700268
269 void invalidateSpriteLocked(const sp<SpriteImpl>& sprite);
270 void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl);
271
Jeff Brown5541de92011-04-11 11:54:25 -0700272 void doUpdateSprites();
273 void doDisposeSurfaces();
274
275 void ensureSurfaceComposerClient();
Linnan Li0defadf2024-05-05 19:17:05 +0800276 sp<SurfaceControl> obtainSurface(int32_t width, int32_t height, ui::LogicalDisplayId displayId,
Arpit Singh80fd68a2024-03-26 18:41:06 +0000277 bool hideOnMirrored);
Jeff Brown5541de92011-04-11 11:54:25 -0700278};
279
280} // namespace android
281
282#endif // _UI_SPRITES_H