OSDN Git Service

auto import from //depot/cupcake/@135843
[android-x86/frameworks-native.git] / libs / ui / SurfaceComposerClient.cpp
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 #define LOG_TAG "SurfaceComposerClient"
18
19 #include <stdint.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25
26 #include <cutils/memory.h>
27
28 #include <utils/Atomic.h>
29 #include <utils/Errors.h>
30 #include <utils/threads.h>
31 #include <utils/KeyedVector.h>
32 #include <utils/IPCThreadState.h>
33 #include <utils/IServiceManager.h>
34 #include <utils/IMemory.h>
35 #include <utils/Log.h>
36
37 #include <ui/ISurfaceComposer.h>
38 #include <ui/ISurfaceFlingerClient.h>
39 #include <ui/ISurface.h>
40 #include <ui/SurfaceComposerClient.h>
41 #include <ui/DisplayInfo.h>
42 #include <ui/Rect.h>
43 #include <ui/Point.h>
44
45 #include <private/ui/SharedState.h>
46 #include <private/ui/LayerState.h>
47 #include <private/ui/SurfaceFlingerSynchro.h>
48
49 #include <pixelflinger/pixelflinger.h>
50
51 #include <utils/BpBinder.h>
52
53 #define VERBOSE(...)    ((void)0)
54 //#define VERBOSE                       LOGD
55
56 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
57 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
58
59 namespace android {
60
61 // ---------------------------------------------------------------------------
62
63 // Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
64 static Mutex                                                gLock;
65 static sp<ISurfaceComposer>                                 gSurfaceManager;
66 static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
67 static SortedVector<sp<SurfaceComposerClient> >             gOpenTransactions;
68 static sp<IMemory>                                          gServerCblkMemory;
69 static volatile surface_flinger_cblk_t*                     gServerCblk;
70
71 const sp<ISurfaceComposer>& _get_surface_manager()
72 {
73     if (gSurfaceManager != 0) {
74         return gSurfaceManager;
75     }
76
77     sp<IBinder> binder;
78     sp<IServiceManager> sm = defaultServiceManager();
79     do {
80         binder = sm->getService(String16("SurfaceFlinger"));
81         if (binder == 0) {
82             LOGW("SurfaceFlinger not published, waiting...");
83             usleep(500000); // 0.5 s
84         }
85     } while(binder == 0);
86     sp<ISurfaceComposer> sc(interface_cast<ISurfaceComposer>(binder));
87
88     Mutex::Autolock _l(gLock);
89     if (gSurfaceManager == 0) {
90         gSurfaceManager = sc;
91     }
92     return gSurfaceManager;
93 }
94
95 static volatile surface_flinger_cblk_t const * get_cblk()
96 {
97     if (gServerCblk == 0) {
98         const sp<ISurfaceComposer>& sm(_get_surface_manager());
99         Mutex::Autolock _l(gLock);
100         if (gServerCblk == 0) {
101             gServerCblkMemory = sm->getCblk();
102             LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
103             gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->pointer();
104             LOGE_IF(gServerCblk==0, "Can't get server control block address");
105         }
106     }
107     return gServerCblk;
108 }
109
110 // ---------------------------------------------------------------------------
111
112 static void copyBlt(const GGLSurface& dst,
113         const GGLSurface& src, const Region& reg)
114 {
115     Region::iterator iterator(reg);
116     if (iterator) {
117         // NOTE: dst and src must be the same format
118         Rect r;
119         const size_t bpp = bytesPerPixel(src.format);
120         const size_t dbpr = dst.stride * bpp;
121         const size_t sbpr = src.stride * bpp;
122         while (iterator.iterate(&r)) {
123             ssize_t h = r.bottom - r.top;
124             if (h) {
125                 size_t size = (r.right - r.left) * bpp;
126                 uint8_t* s = src.data + (r.left + src.stride * r.top) * bpp;
127                 uint8_t* d = dst.data + (r.left + dst.stride * r.top) * bpp;
128                 if (dbpr==sbpr && size==sbpr) {
129                     size *= h;
130                     h = 1;
131                 }
132                 do {
133                     memcpy(d, s, size);
134                     d += dbpr;
135                     s += sbpr;
136                 } while (--h > 0);
137             }
138         }
139     }
140 }
141
142 // ---------------------------------------------------------------------------
143
144 surface_flinger_cblk_t::surface_flinger_cblk_t()
145 {
146 }
147
148 // ---------------------------------------------------------------------------
149
150 per_client_cblk_t::per_client_cblk_t()
151 {
152 }
153
154 // these functions are used by the clients
155 inline status_t per_client_cblk_t::validate(size_t i) const {
156     if (uint32_t(i) >= NUM_LAYERS_MAX)
157         return BAD_INDEX;
158     if (layers[i].swapState & eInvalidSurface)
159         return NO_MEMORY;
160     return NO_ERROR;
161 }
162
163 int32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags)
164 {
165     int32_t index;
166     uint32_t state;
167     int timeout = 0;
168     status_t result;
169     layer_cblk_t * const layer = layers + i;
170     const bool blocking = flags & BLOCKING;
171     const bool inspect  = flags & INSPECT;
172
173     do {
174         state = layer->swapState;
175
176         if (UNLIKELY((state&(eFlipRequested|eNextFlipPending)) == eNextFlipPending)) {
177             LOGE("eNextFlipPending set but eFlipRequested not set, "
178                  "layer=%d (lcblk=%p), state=%08x",
179                  int(i), layer, int(state));
180             return INVALID_OPERATION;
181         }
182
183         if (UNLIKELY(state&eLocked)) {
184             LOGE("eLocked set when entering lock_layer(), "
185                  "layer=%d (lcblk=%p), state=%08x",
186                  int(i), layer, int(state));
187             return WOULD_BLOCK;
188         }
189
190
191             if (state & (eFlipRequested | eNextFlipPending | eResizeRequested
192                         | eInvalidSurface))
193         {
194                 int32_t resizeIndex;
195                 Mutex::Autolock _l(lock);
196                     // might block for a very short amount of time
197                     // will never cause the server to block (trylock())
198
199                 goto start_loop_here;
200
201                 // We block the client if:
202                 // eNextFlipPending:  we've used both buffers already, so we need to
203                 //                    wait for one to become availlable.
204                 // eResizeRequested:  the buffer we're going to acquire is being
205                 //                    resized. Block until it is done.
206                 // eFlipRequested && eBusy: the buffer we're going to acquire is
207                 //                    currently in use by the server.
208                 // eInvalidSurface:   this is a special case, we don't block in this
209                 //                    case, we just return an error.
210
211                 while((state & (eNextFlipPending|eInvalidSurface)) ||
212                       (state & ((resizeIndex) ? eResizeBuffer1 : eResizeBuffer0)) ||
213                       ((state & (eFlipRequested|eBusy)) == (eFlipRequested|eBusy)) )
214                 {
215                     if (state & eInvalidSurface)
216                         return NO_MEMORY;
217
218                     if (!blocking)
219                         return WOULD_BLOCK;
220
221                 timeout = 0;
222                 result = cv.waitRelative(lock, seconds(1));
223                     if (__builtin_expect(result!=NO_ERROR, false)) {
224                     const int newState = layer->swapState;
225                     LOGW(   "lock_layer timed out (is the CPU pegged?) "
226                             "layer=%d, lcblk=%p, state=%08x (was %08x)",
227                             int(i), layer, newState, int(state));
228                     timeout = newState != int(state);
229                 }
230
231                 start_loop_here:
232                     state = layer->swapState;
233                     resizeIndex = (state&eIndex) ^ ((state&eFlipRequested)>>1);
234                 }
235
236             LOGW_IF(timeout,
237                     "lock_layer() timed out but didn't appear to need "
238                     "to be locked and we recovered "
239                     "(layer=%d, lcblk=%p, state=%08x)",
240                     int(i), layer, int(state));
241             }
242
243             // eFlipRequested is not set and cannot be set by another thread: it's
244             // safe to use the first buffer without synchronization.
245
246         // Choose the index depending on eFlipRequested.
247         // When it's set, choose the 'other' buffer.
248         index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
249
250             // make sure this buffer is valid
251             if (layer->surface[index].bits_offset < 0) {
252                 return status_t(layer->surface[index].bits_offset);
253             }
254
255         if (inspect) {
256             // we just want to inspect this layer. don't lock it.
257             goto done;
258         }
259
260             // last thing before we're done, we need to atomically lock the state
261     } while (android_atomic_cmpxchg(state, state|eLocked, &(layer->swapState)));
262
263     VERBOSE("locked layer=%d (lcblk=%p), buffer=%d, state=0x%08x",
264          int(i), layer, int(index), int(state));
265
266     // store the index of the locked buffer (for client use only)
267     layer->flags &= ~eBufferIndex;
268     layer->flags |= ((index << eBufferIndexShift) & eBufferIndex);
269
270 done:
271     return index;
272 }
273
274 uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
275 {
276     // atomically set eFlipRequested and clear eLocked and optionnaly
277     // set eNextFlipPending if eFlipRequested was already set
278
279     layer_cblk_t * const layer = layers + i;
280     int32_t oldvalue, newvalue;
281     do {
282         oldvalue = layer->swapState;
283             // get current value
284
285         newvalue = oldvalue & ~eLocked;
286             // clear eLocked
287
288         newvalue |= eFlipRequested;
289             // set eFlipRequested
290
291         if (oldvalue & eFlipRequested)
292             newvalue |= eNextFlipPending;
293             // if eFlipRequested was alread set, set eNextFlipPending
294
295     } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
296
297     VERBOSE("request pageflip for layer=%d, buffer=%d, state=0x%08x",
298             int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
299             int(newvalue));
300
301     // from this point, the server can kick in at anytime and use the first
302     // buffer, so we cannot use it anymore, and we must use the 'other'
303     // buffer instead (or wait if it is not availlable yet, see lock_layer).
304
305     return newvalue;
306 }
307
308 void per_client_cblk_t::unlock_layer(size_t i)
309 {
310     layer_cblk_t * const layer = layers + i;
311     android_atomic_and(~eLocked, &layer->swapState);
312 }
313
314 // ---------------------------------------------------------------------------
315
316 static inline int compare_type( const layer_state_t& lhs,
317                                 const layer_state_t& rhs) {
318     if (lhs.surface < rhs.surface)  return -1;
319     if (lhs.surface > rhs.surface)  return 1;
320     return 0;
321 }
322
323 SurfaceComposerClient::SurfaceComposerClient()
324 {
325     const sp<ISurfaceComposer>& sm(_get_surface_manager());
326     if (sm == 0) {
327         _init(0, 0);
328         return;
329     }
330
331     _init(sm, sm->createConnection());
332
333     if (mClient != 0) {
334         Mutex::Autolock _l(gLock);
335         VERBOSE("Adding client %p to map", this);
336         gActiveConnections.add(mClient->asBinder(), this);
337     }
338 }
339
340 SurfaceComposerClient::SurfaceComposerClient(
341         const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
342 {
343     _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
344 }
345
346 void SurfaceComposerClient::_init(
347         const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
348 {
349     VERBOSE("Creating client %p, conn %p", this, conn.get());
350
351     mSignalServer = 0;
352     mPrebuiltLayerState = 0;
353     mTransactionOpen = 0;
354     mStatus = NO_ERROR;
355     mControl = 0;
356
357     mClient = conn;
358     if (mClient == 0) {
359         mStatus = NO_INIT;
360         return;
361     }
362
363     mClient->getControlBlocks(&mControlMemory);
364     mSignalServer = new SurfaceFlingerSynchro(sm);
365     mControl = static_cast<per_client_cblk_t *>(mControlMemory->pointer());
366 }
367
368 SurfaceComposerClient::~SurfaceComposerClient()
369 {
370     VERBOSE("Destroying client %p, conn %p", this, mClient.get());
371     dispose();
372 }
373
374 status_t SurfaceComposerClient::initCheck() const
375 {
376     return mStatus;
377 }
378
379 status_t SurfaceComposerClient::validateSurface(
380         per_client_cblk_t const* cblk, Surface const * surface)
381 {
382     SurfaceID index = surface->ID();
383     if (cblk == 0) {
384         LOGE("cblk is null (surface id=%d, identity=%u)",
385                 index, surface->getIdentity());
386         return NO_INIT;
387     }
388
389     status_t err = cblk->validate(index);
390     if (err != NO_ERROR) {
391         LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
392                 index, surface->getIdentity(), err, strerror(-err));
393         return err;
394     }
395
396     if (surface->getIdentity() != uint32_t(cblk->layers[index].identity)) {
397         LOGE("using an invalid surface id=%d, identity=%u should be %d",
398                 index, surface->getIdentity(), cblk->layers[index].identity);
399         return NO_INIT;
400     }
401
402     return NO_ERROR;
403 }
404
405 sp<IBinder> SurfaceComposerClient::connection() const
406 {
407     return (mClient != 0) ? mClient->asBinder() : 0;
408 }
409
410 sp<SurfaceComposerClient>
411 SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
412 {
413     sp<SurfaceComposerClient> client;
414
415     { // scope for lock
416         Mutex::Autolock _l(gLock);
417         client = gActiveConnections.valueFor(conn);
418     }
419
420     if (client == 0) {
421         // Need to make a new client.
422         const sp<ISurfaceComposer>& sm(_get_surface_manager());
423         client = new SurfaceComposerClient(sm, conn);
424         if (client != 0 && client->initCheck() == NO_ERROR) {
425             Mutex::Autolock _l(gLock);
426             gActiveConnections.add(conn, client);
427             //LOGD("we have %d connections", gActiveConnections.size());
428         } else {
429             client.clear();
430         }
431     }
432
433     return client;
434 }
435
436 void SurfaceComposerClient::dispose()
437 {
438     // this can be called more than once.
439
440     sp<IMemory>                 controlMemory;
441     sp<ISurfaceFlingerClient>   client;
442     sp<IMemoryHeap>             surfaceHeap;
443
444     {
445         Mutex::Autolock _lg(gLock);
446         Mutex::Autolock _lm(mLock);
447
448         delete mSignalServer;
449         mSignalServer = 0;
450
451         if (mClient != 0) {
452             client = mClient;
453             mClient.clear();
454
455             ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
456             if (i >= 0 && gActiveConnections.valueAt(i) == this) {
457                 VERBOSE("Removing client %p from map at %d", this, int(i));
458                 gActiveConnections.removeItemsAt(i);
459             }
460         }
461
462         delete mPrebuiltLayerState;
463         mPrebuiltLayerState = 0;
464         controlMemory = mControlMemory;
465         surfaceHeap = mSurfaceHeap;
466         mControlMemory.clear();
467         mSurfaceHeap.clear();
468         mControl = 0;
469         mStatus = NO_INIT;
470     }
471 }
472
473 status_t SurfaceComposerClient::getDisplayInfo(
474         DisplayID dpy, DisplayInfo* info)
475 {
476     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
477         return BAD_VALUE;
478
479     volatile surface_flinger_cblk_t const * cblk = get_cblk();
480     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
481
482     info->w              = dcblk->w;
483     info->h              = dcblk->h;
484     info->orientation    = dcblk->orientation;
485     info->xdpi           = dcblk->xdpi;
486     info->ydpi           = dcblk->ydpi;
487     info->fps            = dcblk->fps;
488     info->density        = dcblk->density;
489     return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
490 }
491
492 ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
493 {
494     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
495         return BAD_VALUE;
496     volatile surface_flinger_cblk_t const * cblk = get_cblk();
497     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
498     return dcblk->w;
499 }
500
501 ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
502 {
503     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
504         return BAD_VALUE;
505     volatile surface_flinger_cblk_t const * cblk = get_cblk();
506     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
507     return dcblk->h;
508 }
509
510 ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
511 {
512     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
513         return BAD_VALUE;
514     volatile surface_flinger_cblk_t const * cblk = get_cblk();
515     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
516     return dcblk->orientation;
517 }
518
519 ssize_t SurfaceComposerClient::getNumberOfDisplays()
520 {
521     volatile surface_flinger_cblk_t const * cblk = get_cblk();
522     uint32_t connected = cblk->connected;
523     int n = 0;
524     while (connected) {
525         if (connected&1) n++;
526         connected >>= 1;
527     }
528     return n;
529 }
530
531 sp<Surface> SurfaceComposerClient::createSurface(
532         int pid,
533         DisplayID display,
534         uint32_t w,
535         uint32_t h,
536         PixelFormat format,
537         uint32_t flags)
538 {
539     sp<Surface> result;
540     if (mStatus == NO_ERROR) {
541         ISurfaceFlingerClient::surface_data_t data;
542         sp<ISurface> surface = mClient->createSurface(&data, pid,
543                 display, w, h, format, flags);
544         if (surface != 0) {
545             if (uint32_t(data.token) < NUM_LAYERS_MAX) {
546                 result = new Surface(this, surface, data, w, h, format, flags);
547             }
548         }
549     }
550     return result;
551 }
552
553 status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
554 {
555     if (mStatus != NO_ERROR)
556         return mStatus;
557
558     // it's okay to destroy a surface while a transaction is open,
559     // (transactions really are a client-side concept)
560     // however, this indicates probably a misuse of the API or a bug
561     // in the client code.
562     LOGW_IF(mTransactionOpen,
563          "Destroying surface while a transaction is open. "
564          "Client %p: destroying surface %d, mTransactionOpen=%d",
565          this, sid, mTransactionOpen);
566
567     status_t err = mClient->destroySurface(sid);
568     return err;
569 }
570
571 status_t SurfaceComposerClient::nextBuffer(Surface* surface,
572                         Surface::SurfaceInfo* info)
573 {
574     SurfaceID index = surface->ID();
575     per_client_cblk_t* const cblk = mControl;
576     status_t err = validateSurface(cblk, surface);
577     if (err != NO_ERROR)
578         return err;
579
580     int32_t backIdx = surface->mBackbufferIndex;
581     layer_cblk_t* const lcblk = &(cblk->layers[index]);
582     const surface_info_t* const front = lcblk->surface + (1-backIdx);
583         info->w      = front->w;
584         info->h      = front->h;
585         info->format = front->format;
586         info->base   = surface->heapBase(1-backIdx);
587         info->bits   = reinterpret_cast<void*>(intptr_t(info->base) + front->bits_offset);
588         info->bpr    = front->bpr;
589
590     return 0;
591 }
592
593 status_t SurfaceComposerClient::lockSurface(
594         Surface* surface,
595         Surface::SurfaceInfo* other,
596         Region* dirty,
597         bool blocking)
598 {
599     Mutex::Autolock _l(surface->getLock());
600
601     SurfaceID index = surface->ID();
602     per_client_cblk_t* const cblk = mControl;
603     status_t err = validateSurface(cblk, surface);
604     if (err != NO_ERROR)
605         return err;
606
607     int32_t backIdx = cblk->lock_layer(size_t(index),
608             per_client_cblk_t::BLOCKING);
609     if (backIdx >= 0) {
610         surface->mBackbufferIndex = backIdx;
611         layer_cblk_t* const lcblk = &(cblk->layers[index]);
612         const surface_info_t* const back = lcblk->surface + backIdx;
613         const surface_info_t* const front = lcblk->surface + (1-backIdx);
614             other->w      = back->w;
615             other->h      = back->h;
616             other->format = back->format;
617             other->base   = surface->heapBase(backIdx);
618             other->bits   = reinterpret_cast<void*>(intptr_t(other->base) + back->bits_offset);
619             other->bpr    = back->bpr;
620
621         const Rect bounds(other->w, other->h);
622         Region newDirtyRegion;
623
624         if (back->flags & surface_info_t::eBufferDirty) {
625             /* it is safe to write *back here, because we're guaranteed
626              * SurfaceFlinger is not touching it (since it just granted
627              * access to us) */
628             const_cast<surface_info_t*>(back)->flags &=
629                     ~surface_info_t::eBufferDirty;
630
631             // content is meaningless in this case and the whole surface
632             // needs to be redrawn.
633
634             newDirtyRegion.set(bounds);
635             if (dirty) {
636                 *dirty = newDirtyRegion;
637             }
638
639             //if (bytesPerPixel(other->format) == 4) {
640             //    android_memset32(
641             //        (uint32_t*)other->bits, 0xFF00FF00, other->h * other->bpr);
642             //} else {
643             //    android_memset16( // fill with green
644             //        (uint16_t*)other->bits, 0x7E0, other->h * other->bpr);
645             //}
646         }
647         else
648         {
649             if (dirty) {
650                 dirty->andSelf(Region(bounds));
651                 newDirtyRegion = *dirty;
652             } else {
653                 newDirtyRegion.set(bounds);
654             }
655
656             Region copyback;
657             if (!(lcblk->flags & eNoCopyBack)) {
658                 const Region previousDirtyRegion(surface->dirtyRegion());
659                 copyback = previousDirtyRegion.subtract(newDirtyRegion);
660             }
661
662             if (!copyback.isEmpty()) {
663                 // copy front to back
664                 GGLSurface cb;
665                     cb.version = sizeof(GGLSurface);
666                     cb.width = back->w;
667                     cb.height = back->h;
668                     cb.stride = back->stride;
669                     cb.data = (GGLubyte*)surface->heapBase(backIdx);
670                     cb.data += back->bits_offset;
671                     cb.format = back->format;
672
673                 GGLSurface t;
674                     t.version = sizeof(GGLSurface);
675                     t.width = front->w;
676                     t.height = front->h;
677                     t.stride = front->stride;
678                     t.data = (GGLubyte*)surface->heapBase(1-backIdx);
679                     t.data += front->bits_offset;
680                     t.format = front->format;
681
682                 //const Region copyback(lcblk->region + 1-backIdx);
683                 copyBlt(cb, t, copyback);
684             }
685         }
686
687         // update dirty region
688         surface->setDirtyRegion(newDirtyRegion);
689     }
690     return (backIdx < 0) ? status_t(backIdx) : status_t(NO_ERROR);
691 }
692
693 void SurfaceComposerClient::_signal_server()
694 {
695     mSignalServer->signal();
696 }
697
698 void SurfaceComposerClient::_send_dirty_region(
699         layer_cblk_t* lcblk, const Region& dirty)
700 {
701     const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
702     flat_region_t* flat_region = lcblk->region + index;
703     status_t err = dirty.write(flat_region, sizeof(flat_region_t));
704     if (err < NO_ERROR) {
705         // region doesn't fit, use the bounds
706         const Region reg(dirty.bounds());
707         reg.write(flat_region, sizeof(flat_region_t));
708     }
709 }
710
711 status_t SurfaceComposerClient::unlockAndPostSurface(Surface* surface)
712 {
713     Mutex::Autolock _l(surface->getLock());
714
715     SurfaceID index = surface->ID();
716     per_client_cblk_t* const cblk = mControl;
717     status_t err = validateSurface(cblk, surface);
718     if (err != NO_ERROR)
719         return err;
720
721     Region dirty(surface->dirtyRegion());
722     const Rect& swapRect(surface->swapRectangle());
723     if (swapRect.isValid()) {
724         dirty.set(swapRect);
725     }
726
727     // transmit the dirty region
728     layer_cblk_t* const lcblk = &(cblk->layers[index]);
729     _send_dirty_region(lcblk, dirty);
730     uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
731     if (!(newstate & eNextFlipPending))
732         _signal_server();
733     return NO_ERROR;
734 }
735
736 status_t SurfaceComposerClient::unlockSurface(Surface* surface)
737 {
738     Mutex::Autolock _l(surface->getLock());
739
740     SurfaceID index = surface->ID();
741     per_client_cblk_t* const cblk = mControl;
742     status_t err = validateSurface(cblk, surface);
743     if (err != NO_ERROR)
744         return err;
745
746     layer_cblk_t* const lcblk = &(cblk->layers[index]);
747     cblk->unlock_layer(size_t(index));
748     return NO_ERROR;
749 }
750
751 void SurfaceComposerClient::openGlobalTransaction()
752 {
753     Mutex::Autolock _l(gLock);
754
755     if (gOpenTransactions.size()) {
756         LOGE("openGlobalTransaction() called more than once. skipping.");
757         return;
758     }
759
760     const size_t N = gActiveConnections.size();
761     VERBOSE("openGlobalTransaction (%ld clients)", N);
762     for (size_t i=0; i<N; i++) {
763         sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
764         if (gOpenTransactions.indexOf(client) < 0) {
765             if (client->openTransaction() == NO_ERROR) {
766                 if (gOpenTransactions.add(client) < 0) {
767                     // Ooops!
768                     LOGE(   "Unable to add a SurfaceComposerClient "
769                             "to the global transaction set (out of memory?)");
770                     client->closeTransaction();
771                     // let it go, it'll fail later when the user
772                     // tries to do something with the transaction
773                 }
774             } else {
775                 LOGE("openTransaction on client %p failed", client.get());
776                 // let it go, it'll fail later when the user
777                 // tries to do something with the transaction
778             }
779         }
780     }
781 }
782
783 void SurfaceComposerClient::closeGlobalTransaction()
784 {
785     gLock.lock();
786         SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
787         gOpenTransactions.clear();
788     gLock.unlock();
789
790     const size_t N = clients.size();
791     VERBOSE("closeGlobalTransaction (%ld clients)", N);
792     if (N == 1) {
793         clients[0]->closeTransaction();
794     } else {
795         const sp<ISurfaceComposer>& sm(_get_surface_manager());
796         sm->openGlobalTransaction();
797         for (size_t i=0; i<N; i++) {
798             clients[i]->closeTransaction();
799         }
800         sm->closeGlobalTransaction();
801     }
802 }
803
804 status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
805 {
806     const sp<ISurfaceComposer>& sm(_get_surface_manager());
807     return sm->freezeDisplay(dpy, flags);
808 }
809
810 status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
811 {
812     const sp<ISurfaceComposer>& sm(_get_surface_manager());
813     return sm->unfreezeDisplay(dpy, flags);
814 }
815
816 int SurfaceComposerClient::setOrientation(DisplayID dpy, int orientation)
817 {
818     const sp<ISurfaceComposer>& sm(_get_surface_manager());
819     return sm->setOrientation(dpy, orientation);
820 }
821
822 status_t SurfaceComposerClient::openTransaction()
823 {
824     if (mStatus != NO_ERROR)
825         return mStatus;
826     Mutex::Autolock _l(mLock);
827     VERBOSE(   "openTransaction (client %p, mTransactionOpen=%d)",
828             this, mTransactionOpen);
829     mTransactionOpen++;
830     if (mPrebuiltLayerState == 0) {
831         mPrebuiltLayerState = new layer_state_t;
832     }
833     return NO_ERROR;
834 }
835
836
837 status_t SurfaceComposerClient::closeTransaction()
838 {
839     if (mStatus != NO_ERROR)
840         return mStatus;
841
842     Mutex::Autolock _l(mLock);
843
844     VERBOSE(   "closeTransaction (client %p, mTransactionOpen=%d)",
845             this, mTransactionOpen);
846
847     if (mTransactionOpen <= 0) {
848         LOGE(   "closeTransaction (client %p, mTransactionOpen=%d) "
849                 "called more times than openTransaction()",
850                 this, mTransactionOpen);
851         return INVALID_OPERATION;
852     }
853
854     if (mTransactionOpen >= 2) {
855         mTransactionOpen--;
856         return NO_ERROR;
857     }
858
859     mTransactionOpen = 0;
860     const ssize_t count = mStates.size();
861     if (count) {
862         mClient->setState(count, mStates.array());
863         mStates.clear();
864     }
865     return NO_ERROR;
866 }
867
868 layer_state_t* SurfaceComposerClient::_get_state_l(const sp<Surface>& surface)
869 {
870     SurfaceID index = surface->ID();
871     per_client_cblk_t* const cblk = mControl;
872     status_t err = validateSurface(cblk, surface.get());
873     if (err != NO_ERROR)
874         return 0;
875
876     // API usage error, do nothing.
877     if (mTransactionOpen<=0) {
878         LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
879                 this, int(index), mTransactionOpen);
880         return 0;
881     }
882
883     // use mPrebuiltLayerState just to find out if we already have it
884     layer_state_t& dummy = *mPrebuiltLayerState;
885     dummy.surface = index;
886     ssize_t i = mStates.indexOf(dummy);
887     if (i < 0) {
888         // we don't have it, add an initialized layer_state to our list
889         i = mStates.add(dummy);
890     }
891     return mStates.editArray() + i;
892 }
893
894 layer_state_t* SurfaceComposerClient::_lockLayerState(const sp<Surface>& surface)
895 {
896     layer_state_t* s;
897     mLock.lock();
898     s = _get_state_l(surface);
899     if (!s) mLock.unlock();
900     return s;
901 }
902
903 void SurfaceComposerClient::_unlockLayerState()
904 {
905     mLock.unlock();
906 }
907
908 status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y)
909 {
910     layer_state_t* s = _lockLayerState(surface);
911     if (!s) return BAD_INDEX;
912     s->what |= ISurfaceComposer::ePositionChanged;
913     s->x = x;
914     s->y = y;
915     _unlockLayerState();
916     return NO_ERROR;
917 }
918
919 status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h)
920 {
921     layer_state_t* s = _lockLayerState(surface);
922     if (!s) return BAD_INDEX;
923     s->what |= ISurfaceComposer::eSizeChanged;
924     s->w = w;
925     s->h = h;
926     _unlockLayerState();
927     return NO_ERROR;
928 }
929
930 status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z)
931 {
932     layer_state_t* s = _lockLayerState(surface);
933     if (!s) return BAD_INDEX;
934     s->what |= ISurfaceComposer::eLayerChanged;
935     s->z = z;
936     _unlockLayerState();
937     return NO_ERROR;
938 }
939
940 status_t SurfaceComposerClient::hide(Surface* surface)
941 {
942     return setFlags(surface, ISurfaceComposer::eLayerHidden,
943             ISurfaceComposer::eLayerHidden);
944 }
945
946 status_t SurfaceComposerClient::show(Surface* surface, int32_t)
947 {
948     return setFlags(surface, 0, ISurfaceComposer::eLayerHidden);
949 }
950
951 status_t SurfaceComposerClient::freeze(Surface* surface)
952 {
953     return setFlags(surface, ISurfaceComposer::eLayerFrozen,
954             ISurfaceComposer::eLayerFrozen);
955 }
956
957 status_t SurfaceComposerClient::unfreeze(Surface* surface)
958 {
959     return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen);
960 }
961
962 status_t SurfaceComposerClient::setFlags(Surface* surface,
963         uint32_t flags, uint32_t mask)
964 {
965     layer_state_t* s = _lockLayerState(surface);
966     if (!s) return BAD_INDEX;
967     s->what |= ISurfaceComposer::eVisibilityChanged;
968     s->flags &= ~mask;
969     s->flags |= (flags & mask);
970     s->mask |= mask;
971     _unlockLayerState();
972     return NO_ERROR;
973 }
974
975
976 status_t SurfaceComposerClient::setTransparentRegionHint(
977         Surface* surface, const Region& transparentRegion)
978 {
979     layer_state_t* s = _lockLayerState(surface);
980     if (!s) return BAD_INDEX;
981     s->what |= ISurfaceComposer::eTransparentRegionChanged;
982     s->transparentRegion = transparentRegion;
983     _unlockLayerState();
984     return NO_ERROR;
985 }
986
987 status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha)
988 {
989     layer_state_t* s = _lockLayerState(surface);
990     if (!s) return BAD_INDEX;
991     s->what |= ISurfaceComposer::eAlphaChanged;
992     s->alpha = alpha;
993     _unlockLayerState();
994     return NO_ERROR;
995 }
996
997 status_t SurfaceComposerClient::setMatrix(
998         Surface* surface,
999         float dsdx, float dtdx,
1000         float dsdy, float dtdy )
1001 {
1002     layer_state_t* s = _lockLayerState(surface);
1003     if (!s) return BAD_INDEX;
1004     s->what |= ISurfaceComposer::eMatrixChanged;
1005     layer_state_t::matrix22_t matrix;
1006     matrix.dsdx = dsdx;
1007     matrix.dtdx = dtdx;
1008     matrix.dsdy = dsdy;
1009     matrix.dtdy = dtdy;
1010     s->matrix = matrix;
1011     _unlockLayerState();
1012     return NO_ERROR;
1013 }
1014
1015 status_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint)
1016 {
1017     layer_state_t* s = _lockLayerState(surface);
1018     if (!s) return BAD_INDEX;
1019     s->what |= ISurfaceComposer::eFreezeTintChanged;
1020     s->tint = tint;
1021     _unlockLayerState();
1022     return NO_ERROR;
1023 }
1024
1025 }; // namespace android
1026