OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / include / private / surfaceflinger / SharedBufferStack.h
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 */