• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <binder/IServiceManager.h>
33 #include <binder/IMemory.h>
34 #include <utils/Log.h>
35 
36 #include <ui/DisplayInfo.h>
37 #include <ui/ISurfaceComposer.h>
38 #include <ui/ISurfaceFlingerClient.h>
39 #include <ui/ISurface.h>
40 #include <ui/SurfaceComposerClient.h>
41 #include <ui/Rect.h>
42 
43 #include <private/ui/LayerState.h>
44 #include <private/ui/SharedBufferStack.h>
45 
46 #define VERBOSE(...)	((void)0)
47 //#define VERBOSE			LOGD
48 
49 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
50 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
51 
52 namespace android {
53 
54 // ---------------------------------------------------------------------------
55 
56 // Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
57 static Mutex                                                gLock;
58 static sp<ISurfaceComposer>                                 gSurfaceManager;
59 static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
60 static SortedVector<sp<SurfaceComposerClient> >             gOpenTransactions;
61 static sp<IMemoryHeap>                                      gServerCblkMemory;
62 static volatile surface_flinger_cblk_t*                     gServerCblk;
63 
getComposerService()64 static sp<ISurfaceComposer> getComposerService()
65 {
66     sp<ISurfaceComposer> sc;
67     Mutex::Autolock _l(gLock);
68     if (gSurfaceManager != 0) {
69         sc = gSurfaceManager;
70     } else {
71         // release the lock while we're waiting...
72         gLock.unlock();
73 
74         sp<IBinder> binder;
75         sp<IServiceManager> sm = defaultServiceManager();
76         do {
77             binder = sm->getService(String16("SurfaceFlinger"));
78             if (binder == 0) {
79                 LOGW("SurfaceFlinger not published, waiting...");
80                 usleep(500000); // 0.5 s
81             }
82         } while(binder == 0);
83 
84         // grab the lock again for updating gSurfaceManager
85         gLock.lock();
86         if (gSurfaceManager == 0) {
87             sc = interface_cast<ISurfaceComposer>(binder);
88             gSurfaceManager = sc;
89         } else {
90             sc = gSurfaceManager;
91         }
92     }
93     return sc;
94 }
95 
get_cblk()96 static volatile surface_flinger_cblk_t const * get_cblk()
97 {
98     if (gServerCblk == 0) {
99         sp<ISurfaceComposer> sm(getComposerService());
100         Mutex::Autolock _l(gLock);
101         if (gServerCblk == 0) {
102             gServerCblkMemory = sm->getCblk();
103             LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
104             gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase();
105             LOGE_IF(gServerCblk==0, "Can't get server control block address");
106         }
107     }
108     return gServerCblk;
109 }
110 
111 // ---------------------------------------------------------------------------
112 
compare_type(const layer_state_t & lhs,const layer_state_t & rhs)113 static inline int compare_type( const layer_state_t& lhs,
114                                 const layer_state_t& rhs) {
115     if (lhs.surface < rhs.surface)  return -1;
116     if (lhs.surface > rhs.surface)  return 1;
117     return 0;
118 }
119 
SurfaceComposerClient()120 SurfaceComposerClient::SurfaceComposerClient()
121 {
122     sp<ISurfaceComposer> sm(getComposerService());
123     if (sm == 0) {
124         _init(0, 0);
125         return;
126     }
127 
128     _init(sm, sm->createConnection());
129 
130     if (mClient != 0) {
131         Mutex::Autolock _l(gLock);
132         VERBOSE("Adding client %p to map", this);
133         gActiveConnections.add(mClient->asBinder(), this);
134     }
135 }
136 
SurfaceComposerClient(const sp<ISurfaceComposer> & sm,const sp<IBinder> & conn)137 SurfaceComposerClient::SurfaceComposerClient(
138         const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
139 {
140     _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
141 }
142 
143 
linkToComposerDeath(const sp<IBinder::DeathRecipient> & recipient,void * cookie,uint32_t flags)144 status_t SurfaceComposerClient::linkToComposerDeath(
145         const sp<IBinder::DeathRecipient>& recipient,
146         void* cookie, uint32_t flags)
147 {
148     sp<ISurfaceComposer> sm(getComposerService());
149     return sm->asBinder()->linkToDeath(recipient, cookie, flags);
150 }
151 
_init(const sp<ISurfaceComposer> & sm,const sp<ISurfaceFlingerClient> & conn)152 void SurfaceComposerClient::_init(
153         const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
154 {
155     VERBOSE("Creating client %p, conn %p", this, conn.get());
156 
157     mPrebuiltLayerState = 0;
158     mTransactionOpen = 0;
159     mStatus = NO_ERROR;
160     mControl = 0;
161 
162     mClient = conn;
163     if (mClient == 0) {
164         mStatus = NO_INIT;
165         return;
166     }
167 
168     mControlMemory = mClient->getControlBlock();
169     mSignalServer = sm;
170     mControl = static_cast<SharedClient *>(mControlMemory->getBase());
171 }
172 
~SurfaceComposerClient()173 SurfaceComposerClient::~SurfaceComposerClient()
174 {
175     VERBOSE("Destroying client %p, conn %p", this, mClient.get());
176     dispose();
177 }
178 
initCheck() const179 status_t SurfaceComposerClient::initCheck() const
180 {
181     return mStatus;
182 }
183 
connection() const184 sp<IBinder> SurfaceComposerClient::connection() const
185 {
186     return (mClient != 0) ? mClient->asBinder() : 0;
187 }
188 
189 sp<SurfaceComposerClient>
clientForConnection(const sp<IBinder> & conn)190 SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
191 {
192     sp<SurfaceComposerClient> client;
193 
194     { // scope for lock
195         Mutex::Autolock _l(gLock);
196         client = gActiveConnections.valueFor(conn);
197     }
198 
199     if (client == 0) {
200         // Need to make a new client.
201         sp<ISurfaceComposer> sm(getComposerService());
202         client = new SurfaceComposerClient(sm, conn);
203         if (client != 0 && client->initCheck() == NO_ERROR) {
204             Mutex::Autolock _l(gLock);
205             gActiveConnections.add(conn, client);
206             //LOGD("we have %d connections", gActiveConnections.size());
207         } else {
208             client.clear();
209         }
210     }
211 
212     return client;
213 }
214 
dispose()215 void SurfaceComposerClient::dispose()
216 {
217     // this can be called more than once.
218 
219     sp<IMemoryHeap>             controlMemory;
220     sp<ISurfaceFlingerClient>   client;
221 
222     {
223         Mutex::Autolock _lg(gLock);
224         Mutex::Autolock _lm(mLock);
225 
226         mSignalServer = 0;
227 
228         if (mClient != 0) {
229             client = mClient;
230             mClient.clear();
231 
232             ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
233             if (i >= 0 && gActiveConnections.valueAt(i) == this) {
234                 VERBOSE("Removing client %p from map at %d", this, int(i));
235                 gActiveConnections.removeItemsAt(i);
236             }
237         }
238 
239         delete mPrebuiltLayerState;
240         mPrebuiltLayerState = 0;
241         controlMemory = mControlMemory;
242         mControlMemory.clear();
243         mControl = 0;
244         mStatus = NO_INIT;
245     }
246 }
247 
getDisplayInfo(DisplayID dpy,DisplayInfo * info)248 status_t SurfaceComposerClient::getDisplayInfo(
249         DisplayID dpy, DisplayInfo* info)
250 {
251     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
252         return BAD_VALUE;
253 
254     volatile surface_flinger_cblk_t const * cblk = get_cblk();
255     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
256 
257     info->w              = dcblk->w;
258     info->h              = dcblk->h;
259     info->orientation    = dcblk->orientation;
260     info->xdpi           = dcblk->xdpi;
261     info->ydpi           = dcblk->ydpi;
262     info->fps            = dcblk->fps;
263     info->density        = dcblk->density;
264     return getPixelFormatInfo(dcblk->format, &(info->pixelFormatInfo));
265 }
266 
getDisplayWidth(DisplayID dpy)267 ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
268 {
269     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
270         return BAD_VALUE;
271     volatile surface_flinger_cblk_t const * cblk = get_cblk();
272     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
273     return dcblk->w;
274 }
275 
getDisplayHeight(DisplayID dpy)276 ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
277 {
278     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
279         return BAD_VALUE;
280     volatile surface_flinger_cblk_t const * cblk = get_cblk();
281     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
282     return dcblk->h;
283 }
284 
getDisplayOrientation(DisplayID dpy)285 ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
286 {
287     if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
288         return BAD_VALUE;
289     volatile surface_flinger_cblk_t const * cblk = get_cblk();
290     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
291     return dcblk->orientation;
292 }
293 
getNumberOfDisplays()294 ssize_t SurfaceComposerClient::getNumberOfDisplays()
295 {
296     volatile surface_flinger_cblk_t const * cblk = get_cblk();
297     uint32_t connected = cblk->connected;
298     int n = 0;
299     while (connected) {
300         if (connected&1) n++;
301         connected >>= 1;
302     }
303     return n;
304 }
305 
306 
signalServer()307 void SurfaceComposerClient::signalServer()
308 {
309     mSignalServer->signal();
310 }
311 
createSurface(int pid,DisplayID display,uint32_t w,uint32_t h,PixelFormat format,uint32_t flags)312 sp<SurfaceControl> SurfaceComposerClient::createSurface(
313         int pid,
314         DisplayID display,
315         uint32_t w,
316         uint32_t h,
317         PixelFormat format,
318         uint32_t flags)
319 {
320     sp<SurfaceControl> result;
321     if (mStatus == NO_ERROR) {
322         ISurfaceFlingerClient::surface_data_t data;
323         sp<ISurface> surface = mClient->createSurface(&data, pid,
324                 display, w, h, format, flags);
325         if (surface != 0) {
326             if (uint32_t(data.token) < NUM_LAYERS_MAX) {
327                 result = new SurfaceControl(this, surface, data, w, h, format, flags);
328             }
329         }
330     }
331     return result;
332 }
333 
destroySurface(SurfaceID sid)334 status_t SurfaceComposerClient::destroySurface(SurfaceID sid)
335 {
336     if (mStatus != NO_ERROR)
337         return mStatus;
338 
339     // it's okay to destroy a surface while a transaction is open,
340     // (transactions really are a client-side concept)
341     // however, this indicates probably a misuse of the API or a bug
342     // in the client code.
343     LOGW_IF(mTransactionOpen,
344          "Destroying surface while a transaction is open. "
345          "Client %p: destroying surface %d, mTransactionOpen=%d",
346          this, sid, mTransactionOpen);
347 
348     status_t err = mClient->destroySurface(sid);
349     return err;
350 }
351 
openGlobalTransaction()352 void SurfaceComposerClient::openGlobalTransaction()
353 {
354     Mutex::Autolock _l(gLock);
355 
356     if (gOpenTransactions.size()) {
357         LOGE("openGlobalTransaction() called more than once. skipping.");
358         return;
359     }
360 
361     const size_t N = gActiveConnections.size();
362     VERBOSE("openGlobalTransaction (%ld clients)", N);
363     for (size_t i=0; i<N; i++) {
364         sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i));
365         if (gOpenTransactions.indexOf(client) < 0) {
366             if (client->openTransaction() == NO_ERROR) {
367                 if (gOpenTransactions.add(client) < 0) {
368                     // Ooops!
369                     LOGE(   "Unable to add a SurfaceComposerClient "
370                             "to the global transaction set (out of memory?)");
371                     client->closeTransaction();
372                     // let it go, it'll fail later when the user
373                     // tries to do something with the transaction
374                 }
375             } else {
376                 LOGE("openTransaction on client %p failed", client.get());
377                 // let it go, it'll fail later when the user
378                 // tries to do something with the transaction
379             }
380         }
381     }
382 }
383 
closeGlobalTransaction()384 void SurfaceComposerClient::closeGlobalTransaction()
385 {
386     gLock.lock();
387         SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
388         gOpenTransactions.clear();
389     gLock.unlock();
390 
391     const size_t N = clients.size();
392     VERBOSE("closeGlobalTransaction (%ld clients)", N);
393 
394     sp<ISurfaceComposer> sm(getComposerService());
395     sm->openGlobalTransaction();
396     for (size_t i=0; i<N; i++) {
397         clients[i]->closeTransaction();
398     }
399     sm->closeGlobalTransaction();
400 
401 }
402 
403 
freezeDisplay(DisplayID dpy,uint32_t flags)404 status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
405 {
406     sp<ISurfaceComposer> sm(getComposerService());
407     return sm->freezeDisplay(dpy, flags);
408 }
409 
unfreezeDisplay(DisplayID dpy,uint32_t flags)410 status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
411 {
412     sp<ISurfaceComposer> sm(getComposerService());
413     return sm->unfreezeDisplay(dpy, flags);
414 }
415 
setOrientation(DisplayID dpy,int orientation,uint32_t flags)416 int SurfaceComposerClient::setOrientation(DisplayID dpy,
417         int orientation, uint32_t flags)
418 {
419     sp<ISurfaceComposer> sm(getComposerService());
420     return sm->setOrientation(dpy, orientation, flags);
421 }
422 
openTransaction()423 status_t SurfaceComposerClient::openTransaction()
424 {
425     if (mStatus != NO_ERROR)
426         return mStatus;
427     Mutex::Autolock _l(mLock);
428     VERBOSE(   "openTransaction (client %p, mTransactionOpen=%d)",
429             this, mTransactionOpen);
430     mTransactionOpen++;
431     if (mPrebuiltLayerState == 0) {
432         mPrebuiltLayerState = new layer_state_t;
433     }
434     return NO_ERROR;
435 }
436 
437 
closeTransaction()438 status_t SurfaceComposerClient::closeTransaction()
439 {
440     if (mStatus != NO_ERROR)
441         return mStatus;
442 
443     Mutex::Autolock _l(mLock);
444 
445     VERBOSE(   "closeTransaction (client %p, mTransactionOpen=%d)",
446             this, mTransactionOpen);
447 
448     if (mTransactionOpen <= 0) {
449         LOGE(   "closeTransaction (client %p, mTransactionOpen=%d) "
450                 "called more times than openTransaction()",
451                 this, mTransactionOpen);
452         return INVALID_OPERATION;
453     }
454 
455     if (mTransactionOpen >= 2) {
456         mTransactionOpen--;
457         return NO_ERROR;
458     }
459 
460     mTransactionOpen = 0;
461     const ssize_t count = mStates.size();
462     if (count) {
463         mClient->setState(count, mStates.array());
464         mStates.clear();
465     }
466     return NO_ERROR;
467 }
468 
_get_state_l(SurfaceID index)469 layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index)
470 {
471     // API usage error, do nothing.
472     if (mTransactionOpen<=0) {
473         LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
474                 this, int(index), mTransactionOpen);
475         return 0;
476     }
477 
478     // use mPrebuiltLayerState just to find out if we already have it
479     layer_state_t& dummy = *mPrebuiltLayerState;
480     dummy.surface = index;
481     ssize_t i = mStates.indexOf(dummy);
482     if (i < 0) {
483         // we don't have it, add an initialized layer_state to our list
484         i = mStates.add(dummy);
485     }
486     return mStates.editArray() + i;
487 }
488 
_lockLayerState(SurfaceID id)489 layer_state_t* SurfaceComposerClient::_lockLayerState(SurfaceID id)
490 {
491     layer_state_t* s;
492     mLock.lock();
493     s = _get_state_l(id);
494     if (!s) mLock.unlock();
495     return s;
496 }
497 
_unlockLayerState()498 void SurfaceComposerClient::_unlockLayerState()
499 {
500     mLock.unlock();
501 }
502 
setPosition(SurfaceID id,int32_t x,int32_t y)503 status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
504 {
505     layer_state_t* s = _lockLayerState(id);
506     if (!s) return BAD_INDEX;
507     s->what |= ISurfaceComposer::ePositionChanged;
508     s->x = x;
509     s->y = y;
510     _unlockLayerState();
511     return NO_ERROR;
512 }
513 
setSize(SurfaceID id,uint32_t w,uint32_t h)514 status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)
515 {
516     layer_state_t* s = _lockLayerState(id);
517     if (!s) return BAD_INDEX;
518     s->what |= ISurfaceComposer::eSizeChanged;
519     s->w = w;
520     s->h = h;
521     _unlockLayerState();
522     return NO_ERROR;
523 }
524 
setLayer(SurfaceID id,int32_t z)525 status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
526 {
527     layer_state_t* s = _lockLayerState(id);
528     if (!s) return BAD_INDEX;
529     s->what |= ISurfaceComposer::eLayerChanged;
530     s->z = z;
531     _unlockLayerState();
532     return NO_ERROR;
533 }
534 
hide(SurfaceID id)535 status_t SurfaceComposerClient::hide(SurfaceID id)
536 {
537     return setFlags(id, ISurfaceComposer::eLayerHidden,
538             ISurfaceComposer::eLayerHidden);
539 }
540 
show(SurfaceID id,int32_t)541 status_t SurfaceComposerClient::show(SurfaceID id, int32_t)
542 {
543     return setFlags(id, 0, ISurfaceComposer::eLayerHidden);
544 }
545 
freeze(SurfaceID id)546 status_t SurfaceComposerClient::freeze(SurfaceID id)
547 {
548     return setFlags(id, ISurfaceComposer::eLayerFrozen,
549             ISurfaceComposer::eLayerFrozen);
550 }
551 
unfreeze(SurfaceID id)552 status_t SurfaceComposerClient::unfreeze(SurfaceID id)
553 {
554     return setFlags(id, 0, ISurfaceComposer::eLayerFrozen);
555 }
556 
setFlags(SurfaceID id,uint32_t flags,uint32_t mask)557 status_t SurfaceComposerClient::setFlags(SurfaceID id,
558         uint32_t flags, uint32_t mask)
559 {
560     layer_state_t* s = _lockLayerState(id);
561     if (!s) return BAD_INDEX;
562     s->what |= ISurfaceComposer::eVisibilityChanged;
563     s->flags &= ~mask;
564     s->flags |= (flags & mask);
565     s->mask |= mask;
566     _unlockLayerState();
567     return NO_ERROR;
568 }
569 
setTransparentRegionHint(SurfaceID id,const Region & transparentRegion)570 status_t SurfaceComposerClient::setTransparentRegionHint(
571         SurfaceID id, const Region& transparentRegion)
572 {
573     layer_state_t* s = _lockLayerState(id);
574     if (!s) return BAD_INDEX;
575     s->what |= ISurfaceComposer::eTransparentRegionChanged;
576     s->transparentRegion = transparentRegion;
577     _unlockLayerState();
578     return NO_ERROR;
579 }
580 
setAlpha(SurfaceID id,float alpha)581 status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)
582 {
583     layer_state_t* s = _lockLayerState(id);
584     if (!s) return BAD_INDEX;
585     s->what |= ISurfaceComposer::eAlphaChanged;
586     s->alpha = alpha;
587     _unlockLayerState();
588     return NO_ERROR;
589 }
590 
setMatrix(SurfaceID id,float dsdx,float dtdx,float dsdy,float dtdy)591 status_t SurfaceComposerClient::setMatrix(
592         SurfaceID id,
593         float dsdx, float dtdx,
594         float dsdy, float dtdy )
595 {
596     layer_state_t* s = _lockLayerState(id);
597     if (!s) return BAD_INDEX;
598     s->what |= ISurfaceComposer::eMatrixChanged;
599     layer_state_t::matrix22_t matrix;
600     matrix.dsdx = dsdx;
601     matrix.dtdx = dtdx;
602     matrix.dsdy = dsdy;
603     matrix.dtdy = dtdy;
604     s->matrix = matrix;
605     _unlockLayerState();
606     return NO_ERROR;
607 }
608 
setFreezeTint(SurfaceID id,uint32_t tint)609 status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
610 {
611     layer_state_t* s = _lockLayerState(id);
612     if (!s) return BAD_INDEX;
613     s->what |= ISurfaceComposer::eFreezeTintChanged;
614     s->tint = tint;
615     _unlockLayerState();
616     return NO_ERROR;
617 }
618 
619 }; // namespace android
620 
621