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.

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

mercurial