widget/gonk/libui/SpriteController.h

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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

mercurial