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