Home | History | Annotate | Download | only in surfaceflinger
      1 /*
      2  * Copyright (C) 2007 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 ANDROID_SF_SHARED_BUFFER_STACK_H
     18 #define ANDROID_SF_SHARED_BUFFER_STACK_H
     19 
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 
     23 #include <cutils/compiler.h>
     24 
     25 #include <utils/Debug.h>
     26 #include <utils/threads.h>
     27 #include <utils/String8.h>
     28 
     29 #include <ui/Rect.h>
     30 
     31 namespace android {
     32 // ---------------------------------------------------------------------------
     33 
     34 /*
     35  * These classes manage a stack of buffers in shared memory.
     36  *
     37  * SharedClient: represents a client with several stacks
     38  * SharedBufferStack: represents a stack of buffers
     39  * SharedBufferClient: manipulates the SharedBufferStack from the client side
     40  * SharedBufferServer: manipulates the SharedBufferStack from the server side
     41  *
     42  * Buffers can be dequeued until there are none available, they can be locked
     43  * unless they are in use by the server, which is only the case for the last
     44  * dequeue-able buffer. When these various conditions are not met, the caller
     45  * waits until the condition is met.
     46  *
     47  */
     48 
     49 // ----------------------------------------------------------------------------
     50 
     51 class Region;
     52 class SharedBufferStack;
     53 class SharedClient;
     54 
     55 // ----------------------------------------------------------------------------
     56 
     57 class SharedBufferStack
     58 {
     59     friend class SharedClient;
     60     friend class SharedBufferBase;
     61     friend class SharedBufferClient;
     62     friend class SharedBufferServer;
     63 
     64 public:
     65     // When changing these values, the COMPILE_TIME_ASSERT at the end of this
     66     // file need to be updated.
     67     static const unsigned int NUM_LAYERS_MAX  = 31;
     68     static const unsigned int NUM_BUFFER_MAX  = 16;
     69     static const unsigned int NUM_BUFFER_MIN  = 2;
     70     static const unsigned int NUM_DISPLAY_MAX = 4;
     71 
     72     struct Statistics { // 4 longs
     73         typedef int32_t usecs_t;
     74         usecs_t  totalTime;
     75         usecs_t  reserved[3];
     76     };
     77 
     78     struct SmallRect {
     79         uint16_t l, t, r, b;
     80     };
     81 
     82     struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
     83         static const unsigned int NUM_RECT_MAX = 5;
     84         uint32_t    count;
     85         SmallRect   rects[NUM_RECT_MAX];
     86     };
     87 
     88     struct BufferData {
     89         FlatRegion dirtyRegion;
     90         SmallRect  crop;
     91         uint8_t transform;
     92         uint8_t reserved[3];
     93     };
     94 
     95     SharedBufferStack();
     96     void init(int32_t identity);
     97     status_t setDirtyRegion(int buffer, const Region& reg);
     98     status_t setCrop(int buffer, const Rect& reg);
     99     status_t setTransform(int buffer, uint8_t transform);
    100     Region getDirtyRegion(int buffer) const;
    101     Rect getCrop(int buffer) const;
    102     uint32_t getTransform(int buffer) const;
    103 
    104     // these attributes are part of the conditions/updates
    105     volatile int32_t head;      // server's current front buffer
    106     volatile int32_t available; // number of dequeue-able buffers
    107     volatile int32_t queued;    // number of buffers waiting for post
    108     volatile int32_t reserved1;
    109     volatile status_t status;   // surface's status code
    110 
    111     // not part of the conditions
    112     volatile int32_t reallocMask;
    113     volatile int8_t index[NUM_BUFFER_MAX];
    114 
    115     int32_t     identity;       // surface's identity (const)
    116     int32_t     token;          // surface's token (for debugging)
    117     Statistics  stats;
    118     int8_t      headBuf;        // last retired buffer
    119     uint8_t     reservedBytes[3];
    120     int32_t     reserved;
    121     BufferData  buffers[NUM_BUFFER_MAX];     // 1024 bytes
    122 };
    123 
    124 // ----------------------------------------------------------------------------
    125 
    126 // 32 KB max
    127 class SharedClient
    128 {
    129 public:
    130     SharedClient();
    131     ~SharedClient();
    132     status_t validate(size_t token) const;
    133 
    134 private:
    135     friend class SharedBufferBase;
    136     friend class SharedBufferClient;
    137     friend class SharedBufferServer;
    138 
    139     // FIXME: this should be replaced by a lock-less primitive
    140     Mutex lock;
    141     Condition cv;
    142     SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
    143 };
    144 
    145 // ============================================================================
    146 
    147 class SharedBufferBase
    148 {
    149 public:
    150     SharedBufferBase(SharedClient* sharedClient, int surface,
    151             int32_t identity);
    152     ~SharedBufferBase();
    153     status_t getStatus() const;
    154     int32_t getIdentity() const;
    155     String8 dump(char const* prefix) const;
    156 
    157 protected:
    158     SharedClient* const mSharedClient;
    159     SharedBufferStack* const mSharedStack;
    160     const int mIdentity;
    161 
    162     friend struct Update;
    163     friend struct QueueUpdate;
    164 
    165     struct ConditionBase {
    166         SharedBufferStack& stack;
    167         inline ConditionBase(SharedBufferBase* sbc)
    168             : stack(*sbc->mSharedStack) { }
    169         virtual ~ConditionBase() { };
    170         virtual bool operator()() const = 0;
    171         virtual const char* name() const = 0;
    172     };
    173     status_t waitForCondition(const ConditionBase& condition);
    174 
    175     struct UpdateBase {
    176         SharedBufferStack& stack;
    177         inline UpdateBase(SharedBufferBase* sbb)
    178             : stack(*sbb->mSharedStack) { }
    179     };
    180     template <typename T>
    181     status_t updateCondition(T update);
    182 };
    183 
    184 template <typename T>
    185 status_t SharedBufferBase::updateCondition(T update) {
    186     SharedClient& client( *mSharedClient );
    187     Mutex::Autolock _l(client.lock);
    188     ssize_t result = update();
    189     client.cv.broadcast();
    190     return result;
    191 }
    192 
    193 // ----------------------------------------------------------------------------
    194 
    195 class SharedBufferClient : public SharedBufferBase
    196 {
    197 public:
    198     SharedBufferClient(SharedClient* sharedClient, int surface, int num,
    199             int32_t identity);
    200 
    201     ssize_t dequeue();
    202     status_t undoDequeue(int buf);
    203 
    204     status_t lock(int buf);
    205     status_t cancel(int buf);
    206     status_t queue(int buf);
    207     bool needNewBuffer(int buffer) const;
    208     status_t setDirtyRegion(int buffer, const Region& reg);
    209     status_t setCrop(int buffer, const Rect& reg);
    210     status_t setTransform(int buffer, uint32_t transform);
    211 
    212     class SetBufferCountCallback {
    213         friend class SharedBufferClient;
    214         virtual status_t operator()(int bufferCount) const = 0;
    215     protected:
    216         virtual ~SetBufferCountCallback() { }
    217     };
    218     status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc);
    219 
    220 private:
    221     friend struct Condition;
    222     friend struct DequeueCondition;
    223     friend struct LockCondition;
    224 
    225     struct QueueUpdate : public UpdateBase {
    226         inline QueueUpdate(SharedBufferBase* sbb);
    227         inline ssize_t operator()();
    228     };
    229 
    230     struct DequeueUpdate : public UpdateBase {
    231         inline DequeueUpdate(SharedBufferBase* sbb);
    232         inline ssize_t operator()();
    233     };
    234 
    235     struct CancelUpdate : public UpdateBase {
    236         int tail, buf;
    237         inline CancelUpdate(SharedBufferBase* sbb, int tail, int buf);
    238         inline ssize_t operator()();
    239     };
    240 
    241     // --
    242 
    243     struct DequeueCondition : public ConditionBase {
    244         inline DequeueCondition(SharedBufferClient* sbc);
    245         inline bool operator()() const;
    246         inline const char* name() const { return "DequeueCondition"; }
    247     };
    248 
    249     struct LockCondition : public ConditionBase {
    250         int buf;
    251         inline LockCondition(SharedBufferClient* sbc, int buf);
    252         inline bool operator()() const;
    253         inline const char* name() const { return "LockCondition"; }
    254     };
    255 
    256     int32_t computeTail() const;
    257 
    258     mutable RWLock mLock;
    259     int mNumBuffers;
    260 
    261     int32_t tail;
    262     int32_t queued_head;
    263     // statistics...
    264     nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
    265 };
    266 
    267 // ----------------------------------------------------------------------------
    268 
    269 class SharedBufferServer
    270     : public SharedBufferBase,
    271       public LightRefBase<SharedBufferServer>
    272 {
    273 public:
    274     SharedBufferServer(SharedClient* sharedClient, int surface, int num,
    275             int32_t identity);
    276 
    277     ssize_t retireAndLock();
    278     void setStatus(status_t status);
    279     status_t reallocateAll();
    280     status_t reallocateAllExcept(int buffer);
    281     int32_t getQueuedCount() const;
    282     Region getDirtyRegion(int buffer) const;
    283     Rect getCrop(int buffer) const;
    284     uint32_t getTransform(int buffer) const;
    285 
    286     status_t resize(int newNumBuffers);
    287 
    288     SharedBufferStack::Statistics getStats() const;
    289 
    290 
    291 private:
    292     friend class LightRefBase<SharedBufferServer>;
    293     ~SharedBufferServer();
    294 
    295     /*
    296      * BufferList is basically a fixed-capacity sorted-vector of
    297      * unsigned 5-bits ints using a 32-bits int as storage.
    298      * it has efficient iterators to find items in the list and not in the list.
    299      */
    300     class BufferList {
    301         size_t mCapacity;
    302         uint32_t mList;
    303     public:
    304         BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX)
    305             : mCapacity(c), mList(0) { }
    306         status_t add(int value);
    307         status_t remove(int value);
    308         uint32_t getMask() const { return mList; }
    309 
    310         class const_iterator {
    311             friend class BufferList;
    312             uint32_t mask, curr;
    313             const_iterator(uint32_t mask) :
    314                 mask(mask), curr(__builtin_clz(mask)) {
    315             }
    316         public:
    317             inline bool operator == (const const_iterator& rhs) const {
    318                 return mask == rhs.mask;
    319             }
    320             inline bool operator != (const const_iterator& rhs) const {
    321                 return mask != rhs.mask;
    322             }
    323             inline int operator *() const { return curr; }
    324             inline const const_iterator& operator ++() {
    325                 mask &= ~(1<<(31-curr));
    326                 curr = __builtin_clz(mask);
    327                 return *this;
    328             }
    329         };
    330 
    331         inline const_iterator begin() const {
    332             return const_iterator(mList);
    333         }
    334         inline const_iterator end() const   {
    335             return const_iterator(0);
    336         }
    337         inline const_iterator free_begin() const {
    338             uint32_t mask = (1 << (32-mCapacity)) - 1;
    339             return const_iterator( ~(mList | mask) );
    340         }
    341     };
    342 
    343     // this protects mNumBuffers and mBufferList
    344     mutable RWLock mLock;
    345     int mNumBuffers;
    346     BufferList mBufferList;
    347 
    348 
    349     struct RetireUpdate : public UpdateBase {
    350         const int numBuffers;
    351         inline RetireUpdate(SharedBufferBase* sbb, int numBuffers);
    352         inline ssize_t operator()();
    353     };
    354 
    355     struct StatusUpdate : public UpdateBase {
    356         const status_t status;
    357         inline StatusUpdate(SharedBufferBase* sbb, status_t status);
    358         inline ssize_t operator()();
    359     };
    360 };
    361 
    362 // ===========================================================================
    363 
    364 struct display_cblk_t
    365 {
    366     uint16_t    w;
    367     uint16_t    h;
    368     uint8_t     format;
    369     uint8_t     orientation;
    370     uint8_t     reserved[2];
    371     float       fps;
    372     float       density;
    373     float       xdpi;
    374     float       ydpi;
    375     uint32_t    pad[2];
    376 };
    377 
    378 struct surface_flinger_cblk_t   // 4KB max
    379 {
    380     uint8_t         connected;
    381     uint8_t         reserved[3];
    382     uint32_t        pad[7];
    383     display_cblk_t  displays[SharedBufferStack::NUM_DISPLAY_MAX];
    384 };
    385 
    386 // ---------------------------------------------------------------------------
    387 
    388 COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
    389 COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
    390 
    391 // ---------------------------------------------------------------------------
    392 }; // namespace android
    393 
    394 #endif /* ANDROID_SF_SHARED_BUFFER_STACK_H */
    395