SurfaceComposerClient.cpp revision 00e8c7a88a5b9c4104a71013a713acd3e4d3b77b
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 <sys/types.h> 21 22#include <utils/Errors.h> 23#include <utils/Log.h> 24#include <utils/Singleton.h> 25#include <utils/SortedVector.h> 26#include <utils/String8.h> 27#include <utils/threads.h> 28 29#include <binder/IMemory.h> 30#include <binder/IServiceManager.h> 31 32#include <ui/DisplayInfo.h> 33 34#include <gui/ISurface.h> 35#include <gui/ISurfaceComposer.h> 36#include <gui/ISurfaceComposerClient.h> 37#include <gui/SurfaceComposerClient.h> 38 39#include <private/gui/ComposerService.h> 40#include <private/gui/LayerState.h> 41 42namespace android { 43// --------------------------------------------------------------------------- 44 45ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService); 46 47ComposerService::ComposerService() 48: Singleton<ComposerService>() { 49 const String16 name("SurfaceFlinger"); 50 while (getService(name, &mComposerService) != NO_ERROR) { 51 usleep(250000); 52 } 53} 54 55sp<ISurfaceComposer> ComposerService::getComposerService() { 56 return ComposerService::getInstance().mComposerService; 57} 58 59// --------------------------------------------------------------------------- 60 61static inline 62int compare_type(const ComposerState& lhs, const ComposerState& rhs) { 63 if (lhs.client < rhs.client) return -1; 64 if (lhs.client > rhs.client) return 1; 65 if (lhs.state.surface < rhs.state.surface) return -1; 66 if (lhs.state.surface > rhs.state.surface) return 1; 67 return 0; 68} 69 70static inline 71int compare_type(const DisplayState& lhs, const DisplayState& rhs) { 72 return compare_type(lhs.token, rhs.token); 73} 74 75class Composer : public Singleton<Composer> 76{ 77 friend class Singleton<Composer>; 78 79 mutable Mutex mLock; 80 SortedVector<ComposerState> mComposerStates; 81 SortedVector<DisplayState > mDisplayStates; 82 uint32_t mForceSynchronous; 83 84 Composer() : Singleton<Composer>(), 85 mForceSynchronous(0) 86 { } 87 88 void closeGlobalTransactionImpl(bool synchronous); 89 90 layer_state_t* getLayerStateLocked( 91 const sp<SurfaceComposerClient>& client, SurfaceID id); 92 93 DisplayState& getDisplayStateLocked(const sp<IBinder>& token); 94 95public: 96 sp<IBinder> createDisplay(); 97 sp<IBinder> getBuiltInDisplay(int32_t id); 98 99 status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id, 100 float x, float y); 101 status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id, 102 uint32_t w, uint32_t h); 103 status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id, 104 int32_t z); 105 status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id, 106 uint32_t flags, uint32_t mask); 107 status_t setTransparentRegionHint( 108 const sp<SurfaceComposerClient>& client, SurfaceID id, 109 const Region& transparentRegion); 110 status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id, 111 float alpha); 112 status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id, 113 float dsdx, float dtdx, float dsdy, float dtdy); 114 status_t setOrientation(int orientation); 115 status_t setCrop(const sp<SurfaceComposerClient>& client, SurfaceID id, 116 const Rect& crop); 117 status_t setLayerStack(const sp<SurfaceComposerClient>& client, 118 SurfaceID id, uint32_t layerStack); 119 120 void setDisplaySurface(const sp<IBinder>& token, const sp<ISurfaceTexture>& surface); 121 void setDisplayLayerStack(const sp<IBinder>& token, uint32_t layerStack); 122 void setDisplayProjection(const sp<IBinder>& token, 123 uint32_t orientation, 124 const Rect& layerStackRect, 125 const Rect& displayRect); 126 127 static void closeGlobalTransaction(bool synchronous) { 128 Composer::getInstance().closeGlobalTransactionImpl(synchronous); 129 } 130}; 131 132ANDROID_SINGLETON_STATIC_INSTANCE(Composer); 133 134// --------------------------------------------------------------------------- 135 136sp<IBinder> Composer::createDisplay() { 137 return ComposerService::getComposerService()->createDisplay(); 138} 139 140sp<IBinder> Composer::getBuiltInDisplay(int32_t id) { 141 return ComposerService::getComposerService()->getBuiltInDisplay(id); 142} 143 144void Composer::closeGlobalTransactionImpl(bool synchronous) { 145 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 146 147 Vector<ComposerState> transaction; 148 Vector<DisplayState> displayTransaction; 149 uint32_t flags = 0; 150 151 { // scope for the lock 152 Mutex::Autolock _l(mLock); 153 transaction = mComposerStates; 154 mComposerStates.clear(); 155 156 displayTransaction = mDisplayStates; 157 mDisplayStates.clear(); 158 159 if (synchronous || mForceSynchronous) { 160 flags |= ISurfaceComposer::eSynchronous; 161 } 162 mForceSynchronous = false; 163 } 164 165 sm->setTransactionState(transaction, displayTransaction, flags); 166} 167 168layer_state_t* Composer::getLayerStateLocked( 169 const sp<SurfaceComposerClient>& client, SurfaceID id) { 170 171 ComposerState s; 172 s.client = client->mClient; 173 s.state.surface = id; 174 175 ssize_t index = mComposerStates.indexOf(s); 176 if (index < 0) { 177 // we don't have it, add an initialized layer_state to our list 178 index = mComposerStates.add(s); 179 } 180 181 ComposerState* const out = mComposerStates.editArray(); 182 return &(out[index].state); 183} 184 185status_t Composer::setPosition(const sp<SurfaceComposerClient>& client, 186 SurfaceID id, float x, float y) { 187 Mutex::Autolock _l(mLock); 188 layer_state_t* s = getLayerStateLocked(client, id); 189 if (!s) 190 return BAD_INDEX; 191 s->what |= layer_state_t::ePositionChanged; 192 s->x = x; 193 s->y = y; 194 return NO_ERROR; 195} 196 197status_t Composer::setSize(const sp<SurfaceComposerClient>& client, 198 SurfaceID id, uint32_t w, uint32_t h) { 199 Mutex::Autolock _l(mLock); 200 layer_state_t* s = getLayerStateLocked(client, id); 201 if (!s) 202 return BAD_INDEX; 203 s->what |= layer_state_t::eSizeChanged; 204 s->w = w; 205 s->h = h; 206 207 // Resizing a surface makes the transaction synchronous. 208 mForceSynchronous = true; 209 210 return NO_ERROR; 211} 212 213status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, 214 SurfaceID id, int32_t z) { 215 Mutex::Autolock _l(mLock); 216 layer_state_t* s = getLayerStateLocked(client, id); 217 if (!s) 218 return BAD_INDEX; 219 s->what |= layer_state_t::eLayerChanged; 220 s->z = z; 221 return NO_ERROR; 222} 223 224status_t Composer::setFlags(const sp<SurfaceComposerClient>& client, 225 SurfaceID id, uint32_t flags, 226 uint32_t mask) { 227 Mutex::Autolock _l(mLock); 228 layer_state_t* s = getLayerStateLocked(client, id); 229 if (!s) 230 return BAD_INDEX; 231 s->what |= layer_state_t::eVisibilityChanged; 232 s->flags &= ~mask; 233 s->flags |= (flags & mask); 234 s->mask |= mask; 235 return NO_ERROR; 236} 237 238status_t Composer::setTransparentRegionHint( 239 const sp<SurfaceComposerClient>& client, SurfaceID id, 240 const Region& transparentRegion) { 241 Mutex::Autolock _l(mLock); 242 layer_state_t* s = getLayerStateLocked(client, id); 243 if (!s) 244 return BAD_INDEX; 245 s->what |= layer_state_t::eTransparentRegionChanged; 246 s->transparentRegion = transparentRegion; 247 return NO_ERROR; 248} 249 250status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client, 251 SurfaceID id, float alpha) { 252 Mutex::Autolock _l(mLock); 253 layer_state_t* s = getLayerStateLocked(client, id); 254 if (!s) 255 return BAD_INDEX; 256 s->what |= layer_state_t::eAlphaChanged; 257 s->alpha = alpha; 258 return NO_ERROR; 259} 260 261status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client, 262 SurfaceID id, uint32_t layerStack) { 263 Mutex::Autolock _l(mLock); 264 layer_state_t* s = getLayerStateLocked(client, id); 265 if (!s) 266 return BAD_INDEX; 267 s->what |= layer_state_t::eLayerStackChanged; 268 s->layerStack = layerStack; 269 return NO_ERROR; 270} 271 272status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client, 273 SurfaceID id, float dsdx, float dtdx, 274 float dsdy, float dtdy) { 275 Mutex::Autolock _l(mLock); 276 layer_state_t* s = getLayerStateLocked(client, id); 277 if (!s) 278 return BAD_INDEX; 279 s->what |= layer_state_t::eMatrixChanged; 280 layer_state_t::matrix22_t matrix; 281 matrix.dsdx = dsdx; 282 matrix.dtdx = dtdx; 283 matrix.dsdy = dsdy; 284 matrix.dtdy = dtdy; 285 s->matrix = matrix; 286 return NO_ERROR; 287} 288 289status_t Composer::setCrop(const sp<SurfaceComposerClient>& client, 290 SurfaceID id, const Rect& crop) { 291 Mutex::Autolock _l(mLock); 292 layer_state_t* s = getLayerStateLocked(client, id); 293 if (!s) 294 return BAD_INDEX; 295 s->what |= layer_state_t::eCropChanged; 296 s->crop = crop; 297 return NO_ERROR; 298} 299 300// --------------------------------------------------------------------------- 301 302DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) { 303 DisplayState s; 304 s.token = token; 305 ssize_t index = mDisplayStates.indexOf(s); 306 if (index < 0) { 307 // we don't have it, add an initialized layer_state to our list 308 s.what = 0; 309 index = mDisplayStates.add(s); 310 } 311 return mDisplayStates.editItemAt(index); 312} 313 314void Composer::setDisplaySurface(const sp<IBinder>& token, 315 const sp<ISurfaceTexture>& surface) { 316 Mutex::Autolock _l(mLock); 317 DisplayState& s(getDisplayStateLocked(token)); 318 s.surface = surface; 319 s.what |= DisplayState::eSurfaceChanged; 320} 321 322void Composer::setDisplayLayerStack(const sp<IBinder>& token, 323 uint32_t layerStack) { 324 Mutex::Autolock _l(mLock); 325 DisplayState& s(getDisplayStateLocked(token)); 326 s.layerStack = layerStack; 327 s.what |= DisplayState::eLayerStackChanged; 328} 329 330void Composer::setDisplayProjection(const sp<IBinder>& token, 331 uint32_t orientation, 332 const Rect& layerStackRect, 333 const Rect& displayRect) { 334 Mutex::Autolock _l(mLock); 335 DisplayState& s(getDisplayStateLocked(token)); 336 s.orientation = orientation; 337 s.viewport = layerStackRect; 338 s.frame = displayRect; 339 s.what |= DisplayState::eDisplayProjectionChanged; 340 mForceSynchronous = true; // TODO: do we actually still need this? 341} 342 343// --------------------------------------------------------------------------- 344 345SurfaceComposerClient::SurfaceComposerClient() 346 : mStatus(NO_INIT), mComposer(Composer::getInstance()) 347{ 348} 349 350void SurfaceComposerClient::onFirstRef() { 351 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 352 if (sm != 0) { 353 sp<ISurfaceComposerClient> conn = sm->createConnection(); 354 if (conn != 0) { 355 mClient = conn; 356 mStatus = NO_ERROR; 357 } 358 } 359} 360 361SurfaceComposerClient::~SurfaceComposerClient() { 362 dispose(); 363} 364 365status_t SurfaceComposerClient::initCheck() const { 366 return mStatus; 367} 368 369sp<IBinder> SurfaceComposerClient::connection() const { 370 return (mClient != 0) ? mClient->asBinder() : 0; 371} 372 373status_t SurfaceComposerClient::linkToComposerDeath( 374 const sp<IBinder::DeathRecipient>& recipient, 375 void* cookie, uint32_t flags) { 376 sp<ISurfaceComposer> sm(ComposerService::getComposerService()); 377 return sm->asBinder()->linkToDeath(recipient, cookie, flags); 378} 379 380void SurfaceComposerClient::dispose() { 381 // this can be called more than once. 382 sp<ISurfaceComposerClient> client; 383 Mutex::Autolock _lm(mLock); 384 if (mClient != 0) { 385 client = mClient; // hold ref while lock is held 386 mClient.clear(); 387 } 388 mStatus = NO_INIT; 389} 390 391sp<SurfaceControl> SurfaceComposerClient::createSurface( 392 const String8& name, 393 uint32_t w, 394 uint32_t h, 395 PixelFormat format, 396 uint32_t flags) 397{ 398 sp<SurfaceControl> result; 399 if (mStatus == NO_ERROR) { 400 ISurfaceComposerClient::surface_data_t data; 401 sp<ISurface> surface = mClient->createSurface(&data, name, 402 w, h, format, flags); 403 if (surface != 0) { 404 result = new SurfaceControl(this, surface, data); 405 } 406 } 407 return result; 408} 409 410sp<IBinder> SurfaceComposerClient::createDisplay() { 411 return Composer::getInstance().createDisplay(); 412} 413 414sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) { 415 return Composer::getInstance().getBuiltInDisplay(id); 416} 417 418status_t SurfaceComposerClient::destroySurface(SurfaceID sid) { 419 if (mStatus != NO_ERROR) 420 return mStatus; 421 status_t err = mClient->destroySurface(sid); 422 return err; 423} 424 425inline Composer& SurfaceComposerClient::getComposer() { 426 return mComposer; 427} 428 429// ---------------------------------------------------------------------------- 430 431void SurfaceComposerClient::openGlobalTransaction() { 432 // Currently a no-op 433} 434 435void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { 436 Composer::closeGlobalTransaction(synchronous); 437} 438 439// ---------------------------------------------------------------------------- 440 441status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) { 442 return getComposer().setCrop(this, id, crop); 443} 444 445status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) { 446 return getComposer().setPosition(this, id, x, y); 447} 448 449status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) { 450 return getComposer().setSize(this, id, w, h); 451} 452 453status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) { 454 return getComposer().setLayer(this, id, z); 455} 456 457status_t SurfaceComposerClient::hide(SurfaceID id) { 458 return getComposer().setFlags(this, id, 459 layer_state_t::eLayerHidden, 460 layer_state_t::eLayerHidden); 461} 462 463status_t SurfaceComposerClient::show(SurfaceID id) { 464 return getComposer().setFlags(this, id, 465 0, 466 layer_state_t::eLayerHidden); 467} 468 469status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags, 470 uint32_t mask) { 471 return getComposer().setFlags(this, id, flags, mask); 472} 473 474status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id, 475 const Region& transparentRegion) { 476 return getComposer().setTransparentRegionHint(this, id, transparentRegion); 477} 478 479status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) { 480 return getComposer().setAlpha(this, id, alpha); 481} 482 483status_t SurfaceComposerClient::setLayerStack(SurfaceID id, uint32_t layerStack) { 484 return getComposer().setLayerStack(this, id, layerStack); 485} 486 487status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx, 488 float dsdy, float dtdy) { 489 return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy); 490} 491 492// ---------------------------------------------------------------------------- 493 494void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token, 495 const sp<ISurfaceTexture>& surface) { 496 Composer::getInstance().setDisplaySurface(token, surface); 497} 498 499void SurfaceComposerClient::setDisplayLayerStack(const sp<IBinder>& token, 500 uint32_t layerStack) { 501 Composer::getInstance().setDisplayLayerStack(token, layerStack); 502} 503 504void SurfaceComposerClient::setDisplayProjection(const sp<IBinder>& token, 505 uint32_t orientation, 506 const Rect& layerStackRect, 507 const Rect& displayRect) { 508 Composer::getInstance().setDisplayProjection(token, orientation, 509 layerStackRect, displayRect); 510} 511 512// ---------------------------------------------------------------------------- 513 514status_t SurfaceComposerClient::getDisplayInfo( 515 const sp<IBinder>& display, DisplayInfo* info) 516{ 517 return ComposerService::getComposerService()->getDisplayInfo(display, info); 518} 519 520// TODO: Remove me. Do not use. 521// This is a compatibility shim for one product whose drivers are depending on 522// this legacy function (when they shouldn't). 523status_t SurfaceComposerClient::getDisplayInfo( 524 int32_t displayId, DisplayInfo* info) 525{ 526 return getDisplayInfo(getBuiltInDisplay(displayId), info); 527} 528 529// ---------------------------------------------------------------------------- 530 531ScreenshotClient::ScreenshotClient() 532 : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) { 533} 534 535status_t ScreenshotClient::update(const sp<IBinder>& display) { 536 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 537 if (s == NULL) return NO_INIT; 538 mHeap = 0; 539 return s->captureScreen(display, &mHeap, 540 &mWidth, &mHeight, &mFormat, 0, 0, 541 0, -1UL); 542} 543 544status_t ScreenshotClient::update(const sp<IBinder>& display, 545 uint32_t reqWidth, uint32_t reqHeight) { 546 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 547 if (s == NULL) return NO_INIT; 548 mHeap = 0; 549 return s->captureScreen(display, &mHeap, 550 &mWidth, &mHeight, &mFormat, reqWidth, reqHeight, 551 0, -1UL); 552} 553 554status_t ScreenshotClient::update(const sp<IBinder>& display, 555 uint32_t reqWidth, uint32_t reqHeight, 556 uint32_t minLayerZ, uint32_t maxLayerZ) { 557 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 558 if (s == NULL) return NO_INIT; 559 mHeap = 0; 560 return s->captureScreen(display, &mHeap, 561 &mWidth, &mHeight, &mFormat, reqWidth, reqHeight, 562 minLayerZ, maxLayerZ); 563} 564 565void ScreenshotClient::release() { 566 mHeap = 0; 567} 568 569void const* ScreenshotClient::getPixels() const { 570 return mHeap->getBase(); 571} 572 573uint32_t ScreenshotClient::getWidth() const { 574 return mWidth; 575} 576 577uint32_t ScreenshotClient::getHeight() const { 578 return mHeight; 579} 580 581PixelFormat ScreenshotClient::getFormat() const { 582 return mFormat; 583} 584 585uint32_t ScreenshotClient::getStride() const { 586 return mWidth; 587} 588 589size_t ScreenshotClient::getSize() const { 590 return mHeap->getSize(); 591} 592 593// ---------------------------------------------------------------------------- 594}; // namespace android 595