SurfaceComposerClient.cpp revision c666cae2d5995097ec49a87e375e2afdd92802b7
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 59static inline sp<ISurfaceComposer> getComposerService() { 60 return ComposerService::getComposerService(); 61} 62 63// --------------------------------------------------------------------------- 64 65// NOTE: this is NOT a member function (it's a friend defined with its 66// declaration). 67static inline 68int compare_type( const ComposerState& lhs, const ComposerState& rhs) { 69 if (lhs.client < rhs.client) return -1; 70 if (lhs.client > rhs.client) return 1; 71 if (lhs.state.surface < rhs.state.surface) return -1; 72 if (lhs.state.surface > rhs.state.surface) return 1; 73 return 0; 74} 75 76class Composer : public Singleton<Composer> 77{ 78 friend class Singleton<Composer>; 79 80 mutable Mutex mLock; 81 SortedVector<ComposerState> mStates; 82 int mOrientation; 83 uint32_t mForceSynchronous; 84 85 Composer() : Singleton<Composer>(), 86 mOrientation(ISurfaceComposer::eOrientationUnchanged), 87 mForceSynchronous(0) 88 { } 89 90 void closeGlobalTransactionImpl(bool synchronous); 91 92 layer_state_t* getLayerStateLocked( 93 const sp<SurfaceComposerClient>& client, SurfaceID id); 94 95public: 96 97 status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id, 98 float x, float y); 99 status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id, 100 uint32_t w, uint32_t h); 101 status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id, 102 int32_t z); 103 status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id, 104 uint32_t flags, uint32_t mask); 105 status_t setTransparentRegionHint( 106 const sp<SurfaceComposerClient>& client, SurfaceID id, 107 const Region& transparentRegion); 108 status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id, 109 float alpha); 110 status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id, 111 float dsdx, float dtdx, float dsdy, float dtdy); 112 status_t setOrientation(int orientation); 113 status_t setCrop(const sp<SurfaceComposerClient>& client, SurfaceID id, 114 const Rect& crop); 115 status_t setLayerStack(const sp<SurfaceComposerClient>& client, 116 SurfaceID id, uint32_t layerStack); 117 118 static void closeGlobalTransaction(bool synchronous) { 119 Composer::getInstance().closeGlobalTransactionImpl(synchronous); 120 } 121}; 122 123ANDROID_SINGLETON_STATIC_INSTANCE(Composer); 124 125// --------------------------------------------------------------------------- 126 127void Composer::closeGlobalTransactionImpl(bool synchronous) { 128 sp<ISurfaceComposer> sm(getComposerService()); 129 130 Vector<ComposerState> transaction; 131 Vector<DisplayState> displayTransaction; 132 uint32_t flags = 0; 133 134 { // scope for the lock 135 Mutex::Autolock _l(mLock); 136 transaction = mStates; 137 mStates.clear(); 138 139 // FIXME: this should be the displays transaction state here 140 DisplayState item; 141 item.orientation = mOrientation; 142 displayTransaction.add(item); 143 144 mOrientation = ISurfaceComposer::eOrientationUnchanged; 145 146 if (synchronous || mForceSynchronous) { 147 flags |= ISurfaceComposer::eSynchronous; 148 } 149 mForceSynchronous = false; 150 } 151 152 sm->setTransactionState(transaction, displayTransaction, flags); 153} 154 155layer_state_t* Composer::getLayerStateLocked( 156 const sp<SurfaceComposerClient>& client, SurfaceID id) { 157 158 ComposerState s; 159 s.client = client->mClient; 160 s.state.surface = id; 161 162 ssize_t index = mStates.indexOf(s); 163 if (index < 0) { 164 // we don't have it, add an initialized layer_state to our list 165 index = mStates.add(s); 166 } 167 168 ComposerState* const out = mStates.editArray(); 169 return &(out[index].state); 170} 171 172status_t Composer::setPosition(const sp<SurfaceComposerClient>& client, 173 SurfaceID id, float x, float y) { 174 Mutex::Autolock _l(mLock); 175 layer_state_t* s = getLayerStateLocked(client, id); 176 if (!s) 177 return BAD_INDEX; 178 s->what |= ISurfaceComposer::ePositionChanged; 179 s->x = x; 180 s->y = y; 181 return NO_ERROR; 182} 183 184status_t Composer::setSize(const sp<SurfaceComposerClient>& client, 185 SurfaceID id, uint32_t w, uint32_t h) { 186 Mutex::Autolock _l(mLock); 187 layer_state_t* s = getLayerStateLocked(client, id); 188 if (!s) 189 return BAD_INDEX; 190 s->what |= ISurfaceComposer::eSizeChanged; 191 s->w = w; 192 s->h = h; 193 194 // Resizing a surface makes the transaction synchronous. 195 mForceSynchronous = true; 196 197 return NO_ERROR; 198} 199 200status_t Composer::setLayer(const sp<SurfaceComposerClient>& client, 201 SurfaceID id, int32_t z) { 202 Mutex::Autolock _l(mLock); 203 layer_state_t* s = getLayerStateLocked(client, id); 204 if (!s) 205 return BAD_INDEX; 206 s->what |= ISurfaceComposer::eLayerChanged; 207 s->z = z; 208 return NO_ERROR; 209} 210 211status_t Composer::setFlags(const sp<SurfaceComposerClient>& client, 212 SurfaceID id, uint32_t flags, 213 uint32_t mask) { 214 Mutex::Autolock _l(mLock); 215 layer_state_t* s = getLayerStateLocked(client, id); 216 if (!s) 217 return BAD_INDEX; 218 s->what |= ISurfaceComposer::eVisibilityChanged; 219 s->flags &= ~mask; 220 s->flags |= (flags & mask); 221 s->mask |= mask; 222 return NO_ERROR; 223} 224 225status_t Composer::setTransparentRegionHint( 226 const sp<SurfaceComposerClient>& client, SurfaceID id, 227 const Region& transparentRegion) { 228 Mutex::Autolock _l(mLock); 229 layer_state_t* s = getLayerStateLocked(client, id); 230 if (!s) 231 return BAD_INDEX; 232 s->what |= ISurfaceComposer::eTransparentRegionChanged; 233 s->transparentRegion = transparentRegion; 234 return NO_ERROR; 235} 236 237status_t Composer::setAlpha(const sp<SurfaceComposerClient>& client, 238 SurfaceID id, float alpha) { 239 Mutex::Autolock _l(mLock); 240 layer_state_t* s = getLayerStateLocked(client, id); 241 if (!s) 242 return BAD_INDEX; 243 s->what |= ISurfaceComposer::eAlphaChanged; 244 s->alpha = alpha; 245 return NO_ERROR; 246} 247 248status_t Composer::setLayerStack(const sp<SurfaceComposerClient>& client, 249 SurfaceID id, uint32_t layerStack) { 250 Mutex::Autolock _l(mLock); 251 layer_state_t* s = getLayerStateLocked(client, id); 252 if (!s) 253 return BAD_INDEX; 254 s->what |= ISurfaceComposer::eLayerStackChanged; 255 s->layerStack = layerStack; 256 return NO_ERROR; 257} 258 259status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client, 260 SurfaceID id, float dsdx, float dtdx, 261 float dsdy, float dtdy) { 262 Mutex::Autolock _l(mLock); 263 layer_state_t* s = getLayerStateLocked(client, id); 264 if (!s) 265 return BAD_INDEX; 266 s->what |= ISurfaceComposer::eMatrixChanged; 267 layer_state_t::matrix22_t matrix; 268 matrix.dsdx = dsdx; 269 matrix.dtdx = dtdx; 270 matrix.dsdy = dsdy; 271 matrix.dtdy = dtdy; 272 s->matrix = matrix; 273 return NO_ERROR; 274} 275 276status_t Composer::setOrientation(int orientation) { 277 Mutex::Autolock _l(mLock); 278 mOrientation = orientation; 279 280 // Changing the orientation makes the transaction synchronous. 281 mForceSynchronous = true; 282 283 return NO_ERROR; 284} 285 286status_t Composer::setCrop(const sp<SurfaceComposerClient>& client, 287 SurfaceID id, const Rect& crop) { 288 Mutex::Autolock _l(mLock); 289 layer_state_t* s = getLayerStateLocked(client, id); 290 if (!s) 291 return BAD_INDEX; 292 s->what |= ISurfaceComposer::eCropChanged; 293 s->crop = crop; 294 return NO_ERROR; 295} 296 297// --------------------------------------------------------------------------- 298 299SurfaceComposerClient::SurfaceComposerClient() 300 : mStatus(NO_INIT), mComposer(Composer::getInstance()) 301{ 302} 303 304void SurfaceComposerClient::onFirstRef() { 305 sp<ISurfaceComposer> sm(getComposerService()); 306 if (sm != 0) { 307 sp<ISurfaceComposerClient> conn = sm->createConnection(); 308 if (conn != 0) { 309 mClient = conn; 310 mStatus = NO_ERROR; 311 } 312 } 313} 314 315SurfaceComposerClient::~SurfaceComposerClient() { 316 dispose(); 317} 318 319status_t SurfaceComposerClient::initCheck() const { 320 return mStatus; 321} 322 323sp<IBinder> SurfaceComposerClient::connection() const { 324 return (mClient != 0) ? mClient->asBinder() : 0; 325} 326 327status_t SurfaceComposerClient::linkToComposerDeath( 328 const sp<IBinder::DeathRecipient>& recipient, 329 void* cookie, uint32_t flags) { 330 sp<ISurfaceComposer> sm(getComposerService()); 331 return sm->asBinder()->linkToDeath(recipient, cookie, flags); 332} 333 334void SurfaceComposerClient::dispose() { 335 // this can be called more than once. 336 sp<ISurfaceComposerClient> client; 337 Mutex::Autolock _lm(mLock); 338 if (mClient != 0) { 339 client = mClient; // hold ref while lock is held 340 mClient.clear(); 341 } 342 mStatus = NO_INIT; 343} 344 345sp<SurfaceControl> SurfaceComposerClient::createSurface( 346 DisplayID display, 347 uint32_t w, 348 uint32_t h, 349 PixelFormat format, 350 uint32_t flags) 351{ 352 String8 name; 353 const size_t SIZE = 128; 354 char buffer[SIZE]; 355 snprintf(buffer, SIZE, "<pid_%d>", getpid()); 356 name.append(buffer); 357 358 return SurfaceComposerClient::createSurface(name, display, 359 w, h, format, flags); 360} 361 362sp<SurfaceControl> SurfaceComposerClient::createSurface( 363 const String8& name, 364 DisplayID display, 365 uint32_t w, 366 uint32_t h, 367 PixelFormat format, 368 uint32_t flags) 369{ 370 sp<SurfaceControl> result; 371 if (mStatus == NO_ERROR) { 372 ISurfaceComposerClient::surface_data_t data; 373 sp<ISurface> surface = mClient->createSurface(&data, name, 374 display, w, h, format, flags); 375 if (surface != 0) { 376 result = new SurfaceControl(this, surface, data); 377 } 378 } 379 return result; 380} 381 382status_t SurfaceComposerClient::destroySurface(SurfaceID sid) { 383 if (mStatus != NO_ERROR) 384 return mStatus; 385 status_t err = mClient->destroySurface(sid); 386 return err; 387} 388 389inline Composer& SurfaceComposerClient::getComposer() { 390 return mComposer; 391} 392 393// ---------------------------------------------------------------------------- 394 395void SurfaceComposerClient::openGlobalTransaction() { 396 // Currently a no-op 397} 398 399void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { 400 Composer::closeGlobalTransaction(synchronous); 401} 402 403// ---------------------------------------------------------------------------- 404 405status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) { 406 return getComposer().setCrop(this, id, crop); 407} 408 409status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) { 410 return getComposer().setPosition(this, id, x, y); 411} 412 413status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h) { 414 return getComposer().setSize(this, id, w, h); 415} 416 417status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z) { 418 return getComposer().setLayer(this, id, z); 419} 420 421status_t SurfaceComposerClient::hide(SurfaceID id) { 422 return getComposer().setFlags(this, id, 423 ISurfaceComposer::eLayerHidden, 424 ISurfaceComposer::eLayerHidden); 425} 426 427status_t SurfaceComposerClient::show(SurfaceID id, int32_t) { 428 return getComposer().setFlags(this, id, 429 0, 430 ISurfaceComposer::eLayerHidden); 431} 432 433status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags, 434 uint32_t mask) { 435 return getComposer().setFlags(this, id, flags, mask); 436} 437 438status_t SurfaceComposerClient::setTransparentRegionHint(SurfaceID id, 439 const Region& transparentRegion) { 440 return getComposer().setTransparentRegionHint(this, id, transparentRegion); 441} 442 443status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha) { 444 return getComposer().setAlpha(this, id, alpha); 445} 446 447status_t SurfaceComposerClient::setLayerStack(SurfaceID id, uint32_t layerStack) { 448 return getComposer().setLayerStack(this, id, layerStack); 449} 450 451status_t SurfaceComposerClient::setMatrix(SurfaceID id, float dsdx, float dtdx, 452 float dsdy, float dtdy) { 453 return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy); 454} 455 456status_t SurfaceComposerClient::setOrientation(DisplayID dpy, 457 int orientation, uint32_t flags) 458{ 459 return Composer::getInstance().setOrientation(orientation); 460} 461 462// ---------------------------------------------------------------------------- 463 464status_t SurfaceComposerClient::getDisplayInfo( 465 DisplayID dpy, DisplayInfo* info) 466{ 467 return getComposerService()->getDisplayInfo(dpy, info); 468} 469 470// ---------------------------------------------------------------------------- 471 472ScreenshotClient::ScreenshotClient() 473 : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) { 474} 475 476status_t ScreenshotClient::update() { 477 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 478 if (s == NULL) return NO_INIT; 479 mHeap = 0; 480 return s->captureScreen(0, &mHeap, 481 &mWidth, &mHeight, &mFormat, 0, 0, 482 0, -1UL); 483} 484 485status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) { 486 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 487 if (s == NULL) return NO_INIT; 488 mHeap = 0; 489 return s->captureScreen(0, &mHeap, 490 &mWidth, &mHeight, &mFormat, reqWidth, reqHeight, 491 0, -1UL); 492} 493 494status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight, 495 uint32_t minLayerZ, uint32_t maxLayerZ) { 496 sp<ISurfaceComposer> s(ComposerService::getComposerService()); 497 if (s == NULL) return NO_INIT; 498 mHeap = 0; 499 return s->captureScreen(0, &mHeap, 500 &mWidth, &mHeight, &mFormat, reqWidth, reqHeight, 501 minLayerZ, maxLayerZ); 502} 503 504void ScreenshotClient::release() { 505 mHeap = 0; 506} 507 508void const* ScreenshotClient::getPixels() const { 509 return mHeap->getBase(); 510} 511 512uint32_t ScreenshotClient::getWidth() const { 513 return mWidth; 514} 515 516uint32_t ScreenshotClient::getHeight() const { 517 return mHeight; 518} 519 520PixelFormat ScreenshotClient::getFormat() const { 521 return mFormat; 522} 523 524uint32_t ScreenshotClient::getStride() const { 525 return mWidth; 526} 527 528size_t ScreenshotClient::getSize() const { 529 return mHeap->getSize(); 530} 531 532// ---------------------------------------------------------------------------- 533}; // namespace android 534