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