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 <gui/SurfaceComposerClient.h> 24 25 #include "SpriteIcon.h" 26 27 namespace android { 28 29 /* 30 * Transformation matrix for a sprite. 31 */ 32 struct SpriteTransformationMatrix { SpriteTransformationMatrixSpriteTransformationMatrix33 inline SpriteTransformationMatrix() : dsdx(1.0f), dtdx(0.0f), dsdy(0.0f), dtdy(1.0f) { } SpriteTransformationMatrixSpriteTransformationMatrix34 inline SpriteTransformationMatrix(float dsdx, float dtdx, float dsdy, float dtdy) : 35 dsdx(dsdx), dtdx(dtdx), dsdy(dsdy), dtdy(dtdy) { } 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 */ 59 class Sprite : public RefBase { 60 protected: Sprite()61 Sprite() { } ~Sprite()62 virtual ~Sprite() { } 63 64 public: 65 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 73 /* Sets the bitmap that is drawn by the sprite. 74 * The sprite retains a copy of the bitmap for subsequent rendering. */ 75 virtual void setIcon(const SpriteIcon& icon) = 0; 76 clearIcon()77 inline void clearIcon() { 78 setIcon(SpriteIcon()); 79 } 80 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; 96 97 /* Sets the id of the display where the sprite should be shown. */ 98 virtual void setDisplayId(ui::LogicalDisplayId displayId) = 0; 99 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; 103 }; 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 */ 116 class SpriteController { 117 public: 118 using ParentSurfaceProvider = std::function<sp<SurfaceControl>(ui::LogicalDisplayId)>; 119 SpriteController(const sp<Looper>& looper, int32_t overlayLayer, ParentSurfaceProvider parent); 120 SpriteController(const SpriteController&) = delete; 121 SpriteController& operator=(const SpriteController&) = delete; 122 virtual ~SpriteController(); 123 124 /* Initialize the callback for the message handler. */ 125 void setHandlerController(const std::shared_ptr<SpriteController>& controller); 126 127 /* Creates a new sprite, initially invisible. The lifecycle of the sprite must not extend beyond 128 * the lifecycle of this SpriteController. */ 129 virtual sp<Sprite> createSprite(); 130 131 /* 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(). */ 136 virtual void openTransaction(); 137 virtual void closeTransaction(); 138 139 private: 140 class Handler : public virtual android::MessageHandler { 141 public: 142 enum { MSG_UPDATE_SPRITES, MSG_DISPOSE_SURFACES }; 143 144 void handleMessage(const Message& message) override; 145 std::weak_ptr<SpriteController> spriteController; 146 }; 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, 156 DIRTY_DISPLAY_ID = 1 << 7, 157 DIRTY_ICON_STYLE = 1 << 8, 158 DIRTY_DRAW_DROP_SHADOW = 1 << 9, 159 DIRTY_SKIP_SCREENSHOT = 1 << 10, 160 }; 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. 166 * Note that the SpriteIcon holds a reference to a shared (and immutable) bitmap. */ 167 struct SpriteState { 168 uint32_t dirty{0}; 169 170 SpriteIcon icon; 171 bool visible{false}; 172 float positionX{0}; 173 float positionY{0}; 174 int32_t layer{0}; 175 float alpha{1.0f}; 176 SpriteTransformationMatrix transformationMatrix; 177 ui::LogicalDisplayId displayId{ui::LogicalDisplayId::DEFAULT}; 178 179 sp<SurfaceControl> surfaceControl; 180 int32_t surfaceWidth{0}; 181 int32_t surfaceHeight{0}; 182 bool surfaceDrawn{false}; 183 bool surfaceVisible{false}; 184 bool skipScreenshot{false}; 185 wantSurfaceVisibleSpriteState186 inline bool wantSurfaceVisible() const { 187 return visible && alpha > 0.0f && icon.isValid(); 188 } 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: 203 explicit SpriteImpl(SpriteController& controller); 204 205 virtual void setIcon(const SpriteIcon& icon); 206 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); 211 virtual void setDisplayId(ui::LogicalDisplayId displayId); 212 virtual void setSkipScreenshot(bool skip); 213 getStateLocked()214 inline const SpriteState& getStateLocked() const { 215 return mLocked.state; 216 } 217 resetDirtyLocked()218 inline void resetDirtyLocked() { 219 mLocked.state.dirty = 0; 220 } 221 setSurfaceLocked(const sp<SurfaceControl> & surfaceControl,int32_t width,int32_t height,bool drawn,bool visible)222 inline void setSurfaceLocked(const sp<SurfaceControl>& surfaceControl, 223 int32_t width, int32_t height, bool drawn, bool visible) { 224 mLocked.state.surfaceControl = surfaceControl; 225 mLocked.state.surfaceWidth = width; 226 mLocked.state.surfaceHeight = height; 227 mLocked.state.surfaceDrawn = drawn; 228 mLocked.state.surfaceVisible = visible; 229 } 230 231 private: 232 SpriteController& mController; 233 234 struct Locked { 235 SpriteState state; 236 } mLocked; // guarded by mController->mLock 237 238 void invalidateLocked(uint32_t dirty); 239 }; 240 241 /* Stores temporary information collected during the sprite update cycle. */ 242 struct SpriteUpdate { SpriteUpdateSpriteUpdate243 inline SpriteUpdate() : surfaceChanged(false) { } SpriteUpdateSpriteUpdate244 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; 257 sp<Handler> mHandler; 258 ParentSurfaceProvider mParentSurfaceProvider; 259 260 sp<SurfaceComposerClient> mSurfaceComposerClient; 261 262 struct Locked { 263 std::vector<sp<SpriteImpl>> invalidatedSprites; 264 std::vector<sp<SurfaceControl>> disposedSurfaces; 265 uint32_t transactionNestingCount; 266 bool deferredSpriteUpdate; 267 } mLocked; // guarded by mLock 268 269 void invalidateSpriteLocked(const sp<SpriteImpl>& sprite); 270 void disposeSurfaceLocked(const sp<SurfaceControl>& surfaceControl); 271 272 void doUpdateSprites(); 273 void doDisposeSurfaces(); 274 275 void ensureSurfaceComposerClient(); 276 sp<SurfaceControl> obtainSurface(int32_t width, int32_t height, ui::LogicalDisplayId displayId, 277 bool hideOnMirrored); 278 }; 279 280 } // namespace android 281 282 #endif // _UI_SPRITES_H 283