SurfaceFlinger.cpp revision 0dd593f22352a0863223fa4ea7e37e926b99282e
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#include <stdlib.h> 18#include <stdio.h> 19#include <stdint.h> 20#include <unistd.h> 21#include <fcntl.h> 22#include <errno.h> 23#include <math.h> 24#include <limits.h> 25#include <sys/types.h> 26#include <sys/stat.h> 27#include <sys/ioctl.h> 28 29#include <cutils/log.h> 30#include <cutils/properties.h> 31 32#include <binder/IPCThreadState.h> 33#include <binder/IServiceManager.h> 34#include <binder/MemoryHeapBase.h> 35#include <binder/PermissionCache.h> 36 37#include <utils/String8.h> 38#include <utils/String16.h> 39#include <utils/StopWatch.h> 40 41#include <ui/GraphicBufferAllocator.h> 42#include <ui/GraphicLog.h> 43#include <ui/PixelFormat.h> 44 45#include <pixelflinger/pixelflinger.h> 46#include <GLES/gl.h> 47 48#include "clz.h" 49#include "GLExtensions.h" 50#include "Layer.h" 51#include "LayerDim.h" 52#include "SurfaceFlinger.h" 53 54#include "DisplayHardware/DisplayHardware.h" 55#include "DisplayHardware/HWComposer.h" 56 57#include <private/surfaceflinger/SharedBufferStack.h> 58 59/* ideally AID_GRAPHICS would be in a semi-public header 60 * or there would be a way to map a user/group name to its id 61 */ 62#ifndef AID_GRAPHICS 63#define AID_GRAPHICS 1003 64#endif 65 66#define DISPLAY_COUNT 1 67 68namespace android { 69// --------------------------------------------------------------------------- 70 71const String16 sHardwareTest("android.permission.HARDWARE_TEST"); 72const String16 sAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"); 73const String16 sReadFramebuffer("android.permission.READ_FRAME_BUFFER"); 74const String16 sDump("android.permission.DUMP"); 75 76// --------------------------------------------------------------------------- 77 78SurfaceFlinger::SurfaceFlinger() 79 : BnSurfaceComposer(), Thread(false), 80 mTransactionFlags(0), 81 mTransactionCount(0), 82 mResizeTransationPending(false), 83 mLayersRemoved(false), 84 mBootTime(systemTime()), 85 mVisibleRegionsDirty(false), 86 mHwWorkListDirty(false), 87 mDeferReleaseConsole(false), 88 mFreezeDisplay(false), 89 mElectronBeamAnimationMode(0), 90 mFreezeCount(0), 91 mFreezeDisplayTime(0), 92 mDebugRegion(0), 93 mDebugBackground(0), 94 mDebugDisableHWC(0), 95 mDebugInSwapBuffers(0), 96 mLastSwapBufferTime(0), 97 mDebugInTransaction(0), 98 mLastTransactionTime(0), 99 mBootFinished(false), 100 mConsoleSignals(0), 101 mSecureFrameBuffer(0) 102{ 103 init(); 104} 105 106void SurfaceFlinger::init() 107{ 108 LOGI("SurfaceFlinger is starting"); 109 110 // debugging stuff... 111 char value[PROPERTY_VALUE_MAX]; 112 property_get("debug.sf.showupdates", value, "0"); 113 mDebugRegion = atoi(value); 114 property_get("debug.sf.showbackground", value, "0"); 115 mDebugBackground = atoi(value); 116 117 LOGI_IF(mDebugRegion, "showupdates enabled"); 118 LOGI_IF(mDebugBackground, "showbackground enabled"); 119} 120 121SurfaceFlinger::~SurfaceFlinger() 122{ 123 glDeleteTextures(1, &mWormholeTexName); 124} 125 126sp<IMemoryHeap> SurfaceFlinger::getCblk() const 127{ 128 return mServerHeap; 129} 130 131sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() 132{ 133 sp<ISurfaceComposerClient> bclient; 134 sp<Client> client(new Client(this)); 135 status_t err = client->initCheck(); 136 if (err == NO_ERROR) { 137 bclient = client; 138 } 139 return bclient; 140} 141 142sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc() 143{ 144 sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc()); 145 return gba; 146} 147 148const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const 149{ 150 LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy); 151 const GraphicPlane& plane(mGraphicPlanes[dpy]); 152 return plane; 153} 154 155GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) 156{ 157 return const_cast<GraphicPlane&>( 158 const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy)); 159} 160 161void SurfaceFlinger::bootFinished() 162{ 163 const nsecs_t now = systemTime(); 164 const nsecs_t duration = now - mBootTime; 165 LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) ); 166 mBootFinished = true; 167 property_set("ctl.stop", "bootanim"); 168} 169 170void SurfaceFlinger::onFirstRef() 171{ 172 run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY); 173 174 // Wait for the main thread to be done with its initialization 175 mReadyToRunBarrier.wait(); 176} 177 178static inline uint16_t pack565(int r, int g, int b) { 179 return (r<<11)|(g<<5)|b; 180} 181 182status_t SurfaceFlinger::readyToRun() 183{ 184 LOGI( "SurfaceFlinger's main thread ready to run. " 185 "Initializing graphics H/W..."); 186 187 // we only support one display currently 188 int dpy = 0; 189 190 { 191 // initialize the main display 192 GraphicPlane& plane(graphicPlane(dpy)); 193 DisplayHardware* const hw = new DisplayHardware(this, dpy); 194 plane.setDisplayHardware(hw); 195 } 196 197 // create the shared control-block 198 mServerHeap = new MemoryHeapBase(4096, 199 MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); 200 LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); 201 202 mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); 203 LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); 204 205 new(mServerCblk) surface_flinger_cblk_t; 206 207 // initialize primary screen 208 // (other display should be initialized in the same manner, but 209 // asynchronously, as they could come and go. None of this is supported 210 // yet). 211 const GraphicPlane& plane(graphicPlane(dpy)); 212 const DisplayHardware& hw = plane.displayHardware(); 213 const uint32_t w = hw.getWidth(); 214 const uint32_t h = hw.getHeight(); 215 const uint32_t f = hw.getFormat(); 216 hw.makeCurrent(); 217 218 // initialize the shared control block 219 mServerCblk->connected |= 1<<dpy; 220 display_cblk_t* dcblk = mServerCblk->displays + dpy; 221 memset(dcblk, 0, sizeof(display_cblk_t)); 222 dcblk->w = plane.getWidth(); 223 dcblk->h = plane.getHeight(); 224 dcblk->format = f; 225 dcblk->orientation = ISurfaceComposer::eOrientationDefault; 226 dcblk->xdpi = hw.getDpiX(); 227 dcblk->ydpi = hw.getDpiY(); 228 dcblk->fps = hw.getRefreshRate(); 229 dcblk->density = hw.getDensity(); 230 231 // Initialize OpenGL|ES 232 glPixelStorei(GL_UNPACK_ALIGNMENT, 4); 233 glPixelStorei(GL_PACK_ALIGNMENT, 4); 234 glEnableClientState(GL_VERTEX_ARRAY); 235 glEnable(GL_SCISSOR_TEST); 236 glShadeModel(GL_FLAT); 237 glDisable(GL_DITHER); 238 glDisable(GL_CULL_FACE); 239 240 const uint16_t g0 = pack565(0x0F,0x1F,0x0F); 241 const uint16_t g1 = pack565(0x17,0x2f,0x17); 242 const uint16_t textureData[4] = { g0, g1, g1, g0 }; 243 glGenTextures(1, &mWormholeTexName); 244 glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 245 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 246 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 247 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 248 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 249 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, 250 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData); 251 252 glViewport(0, 0, w, h); 253 glMatrixMode(GL_PROJECTION); 254 glLoadIdentity(); 255 glOrthof(0, w, h, 0, 0, 1); 256 257 mReadyToRunBarrier.open(); 258 259 /* 260 * We're now ready to accept clients... 261 */ 262 263 // start boot animation 264 property_set("ctl.start", "bootanim"); 265 266 return NO_ERROR; 267} 268 269// ---------------------------------------------------------------------------- 270#if 0 271#pragma mark - 272#pragma mark Events Handler 273#endif 274 275void SurfaceFlinger::waitForEvent() 276{ 277 while (true) { 278 nsecs_t timeout = -1; 279 const nsecs_t freezeDisplayTimeout = ms2ns(5000); 280 if (UNLIKELY(isFrozen())) { 281 // wait 5 seconds 282 const nsecs_t now = systemTime(); 283 if (mFreezeDisplayTime == 0) { 284 mFreezeDisplayTime = now; 285 } 286 nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime); 287 timeout = waitTime>0 ? waitTime : 0; 288 } 289 290 sp<MessageBase> msg = mEventQueue.waitMessage(timeout); 291 292 // see if we timed out 293 if (isFrozen()) { 294 const nsecs_t now = systemTime(); 295 nsecs_t frozenTime = (now - mFreezeDisplayTime); 296 if (frozenTime >= freezeDisplayTimeout) { 297 // we timed out and are still frozen 298 LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d", 299 mFreezeDisplay, mFreezeCount); 300 mFreezeDisplayTime = 0; 301 mFreezeCount = 0; 302 mFreezeDisplay = false; 303 } 304 } 305 306 if (msg != 0) { 307 switch (msg->what) { 308 case MessageQueue::INVALIDATE: 309 // invalidate message, just return to the main loop 310 return; 311 } 312 } 313 } 314} 315 316void SurfaceFlinger::signalEvent() { 317 mEventQueue.invalidate(); 318} 319 320bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const { 321 Mutex::Autolock _l(mStateLock); 322 sp<IBinder> surfBinder(surface->asBinder()); 323 324 // Check the visible layer list for the ISurface 325 const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 326 size_t count = currentLayers.size(); 327 for (size_t i=0 ; i<count ; i++) { 328 const sp<LayerBase>& layer(currentLayers[i]); 329 sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 330 if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) { 331 return true; 332 } 333 } 334 335 // Check the layers in the purgatory. This check is here so that if a 336 // Surface gets destroyed before all the clients are done using it, the 337 // error will not be reported as "surface XYZ is not authenticated", but 338 // will instead fail later on when the client tries to use the surface, 339 // which should be reported as "surface XYZ returned an -ENODEV". The 340 // purgatorized layers are no less authentic than the visible ones, so this 341 // should not cause any harm. 342 size_t purgatorySize = mLayerPurgatory.size(); 343 for (size_t i=0 ; i<purgatorySize ; i++) { 344 const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 345 sp<LayerBaseClient> lbc(layer->getLayerBaseClient()); 346 if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) { 347 return true; 348 } 349 } 350 351 return false; 352} 353 354status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg, 355 nsecs_t reltime, uint32_t flags) 356{ 357 return mEventQueue.postMessage(msg, reltime, flags); 358} 359 360status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg, 361 nsecs_t reltime, uint32_t flags) 362{ 363 status_t res = mEventQueue.postMessage(msg, reltime, flags); 364 if (res == NO_ERROR) { 365 msg->wait(); 366 } 367 return res; 368} 369 370// ---------------------------------------------------------------------------- 371#if 0 372#pragma mark - 373#pragma mark Main loop 374#endif 375 376bool SurfaceFlinger::threadLoop() 377{ 378 waitForEvent(); 379 380 // call Layer's destructor 381 handleDestroyLayers(); 382 383 // check for transactions 384 if (UNLIKELY(mConsoleSignals)) { 385 handleConsoleEvents(); 386 } 387 388 if (LIKELY(mTransactionCount == 0)) { 389 // if we're in a global transaction, don't do anything. 390 const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 391 uint32_t transactionFlags = peekTransactionFlags(mask); 392 if (LIKELY(transactionFlags)) { 393 handleTransaction(transactionFlags); 394 } 395 } 396 397 // post surfaces (if needed) 398 handlePageFlip(); 399 400 if (UNLIKELY(mHwWorkListDirty)) { 401 // build the h/w work list 402 handleWorkList(); 403 } 404 405 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 406 if (LIKELY(hw.canDraw() && !isFrozen())) { 407 // repaint the framebuffer (if needed) 408 409 const int index = hw.getCurrentBufferIndex(); 410 GraphicLog& logger(GraphicLog::getInstance()); 411 412 logger.log(GraphicLog::SF_REPAINT, index); 413 handleRepaint(); 414 415 // inform the h/w that we're done compositing 416 logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index); 417 hw.compositionComplete(); 418 419 logger.log(GraphicLog::SF_SWAP_BUFFERS, index); 420 postFramebuffer(); 421 422 logger.log(GraphicLog::SF_REPAINT_DONE, index); 423 } else { 424 // pretend we did the post 425 hw.compositionComplete(); 426 usleep(16667); // 60 fps period 427 } 428 return true; 429} 430 431void SurfaceFlinger::postFramebuffer() 432{ 433 if (!mInvalidRegion.isEmpty()) { 434 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 435 const nsecs_t now = systemTime(); 436 mDebugInSwapBuffers = now; 437 hw.flip(mInvalidRegion); 438 mLastSwapBufferTime = systemTime() - now; 439 mDebugInSwapBuffers = 0; 440 mInvalidRegion.clear(); 441 } 442} 443 444void SurfaceFlinger::handleConsoleEvents() 445{ 446 // something to do with the console 447 const DisplayHardware& hw = graphicPlane(0).displayHardware(); 448 449 int what = android_atomic_and(0, &mConsoleSignals); 450 if (what & eConsoleAcquired) { 451 hw.acquireScreen(); 452 // this is a temporary work-around, eventually this should be called 453 // by the power-manager 454 SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode); 455 } 456 457 if (mDeferReleaseConsole && hw.isScreenAcquired()) { 458 // We got the release signal before the acquire signal 459 mDeferReleaseConsole = false; 460 hw.releaseScreen(); 461 } 462 463 if (what & eConsoleReleased) { 464 if (hw.isScreenAcquired()) { 465 hw.releaseScreen(); 466 } else { 467 mDeferReleaseConsole = true; 468 } 469 } 470 471 mDirtyRegion.set(hw.bounds()); 472} 473 474void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) 475{ 476 Mutex::Autolock _l(mStateLock); 477 const nsecs_t now = systemTime(); 478 mDebugInTransaction = now; 479 480 // Here we're guaranteed that some transaction flags are set 481 // so we can call handleTransactionLocked() unconditionally. 482 // We call getTransactionFlags(), which will also clear the flags, 483 // with mStateLock held to guarantee that mCurrentState won't change 484 // until the transaction is committed. 485 486 const uint32_t mask = eTransactionNeeded | eTraversalNeeded; 487 transactionFlags = getTransactionFlags(mask); 488 handleTransactionLocked(transactionFlags); 489 490 mLastTransactionTime = systemTime() - now; 491 mDebugInTransaction = 0; 492 invalidateHwcGeometry(); 493 // here the transaction has been committed 494} 495 496void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) 497{ 498 const LayerVector& currentLayers(mCurrentState.layersSortedByZ); 499 const size_t count = currentLayers.size(); 500 501 /* 502 * Traversal of the children 503 * (perform the transaction for each of them if needed) 504 */ 505 506 const bool layersNeedTransaction = transactionFlags & eTraversalNeeded; 507 if (layersNeedTransaction) { 508 for (size_t i=0 ; i<count ; i++) { 509 const sp<LayerBase>& layer = currentLayers[i]; 510 uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); 511 if (!trFlags) continue; 512 513 const uint32_t flags = layer->doTransaction(0); 514 if (flags & Layer::eVisibleRegion) 515 mVisibleRegionsDirty = true; 516 } 517 } 518 519 /* 520 * Perform our own transaction if needed 521 */ 522 523 if (transactionFlags & eTransactionNeeded) { 524 if (mCurrentState.orientation != mDrawingState.orientation) { 525 // the orientation has changed, recompute all visible regions 526 // and invalidate everything. 527 528 const int dpy = 0; 529 const int orientation = mCurrentState.orientation; 530 const uint32_t type = mCurrentState.orientationType; 531 GraphicPlane& plane(graphicPlane(dpy)); 532 plane.setOrientation(orientation); 533 534 // update the shared control block 535 const DisplayHardware& hw(plane.displayHardware()); 536 volatile display_cblk_t* dcblk = mServerCblk->displays + dpy; 537 dcblk->orientation = orientation; 538 dcblk->w = plane.getWidth(); 539 dcblk->h = plane.getHeight(); 540 541 mVisibleRegionsDirty = true; 542 mDirtyRegion.set(hw.bounds()); 543 } 544 545 if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) { 546 // freezing or unfreezing the display -> trigger animation if needed 547 mFreezeDisplay = mCurrentState.freezeDisplay; 548 if (mFreezeDisplay) 549 mFreezeDisplayTime = 0; 550 } 551 552 if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) { 553 // layers have been added 554 mVisibleRegionsDirty = true; 555 } 556 557 // some layers might have been removed, so 558 // we need to update the regions they're exposing. 559 if (mLayersRemoved) { 560 mLayersRemoved = false; 561 mVisibleRegionsDirty = true; 562 const LayerVector& previousLayers(mDrawingState.layersSortedByZ); 563 const size_t count = previousLayers.size(); 564 for (size_t i=0 ; i<count ; i++) { 565 const sp<LayerBase>& layer(previousLayers[i]); 566 if (currentLayers.indexOf( layer ) < 0) { 567 // this layer is not visible anymore 568 mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); 569 } 570 } 571 } 572 } 573 574 commitTransaction(); 575} 576 577void SurfaceFlinger::destroyLayer(LayerBase const* layer) 578{ 579 Mutex::Autolock _l(mDestroyedLayerLock); 580 mDestroyedLayers.add(layer); 581 signalEvent(); 582} 583 584void SurfaceFlinger::handleDestroyLayers() 585{ 586 Vector<LayerBase const *> destroyedLayers; 587 588 { // scope for the lock 589 Mutex::Autolock _l(mDestroyedLayerLock); 590 destroyedLayers = mDestroyedLayers; 591 mDestroyedLayers.clear(); 592 } 593 594 // call destructors without a lock held 595 const size_t count = destroyedLayers.size(); 596 for (size_t i=0 ; i<count ; i++) { 597 //LOGD("destroying %s", destroyedLayers[i]->getName().string()); 598 delete destroyedLayers[i]; 599 } 600} 601 602sp<FreezeLock> SurfaceFlinger::getFreezeLock() const 603{ 604 return new FreezeLock(const_cast<SurfaceFlinger *>(this)); 605} 606 607void SurfaceFlinger::computeVisibleRegions( 608 const LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion) 609{ 610 const GraphicPlane& plane(graphicPlane(0)); 611 const Transform& planeTransform(plane.transform()); 612 const DisplayHardware& hw(plane.displayHardware()); 613 const Region screenRegion(hw.bounds()); 614 615 Region aboveOpaqueLayers; 616 Region aboveCoveredLayers; 617 Region dirty; 618 619 bool secureFrameBuffer = false; 620 621 size_t i = currentLayers.size(); 622 while (i--) { 623 const sp<LayerBase>& layer = currentLayers[i]; 624 layer->validateVisibility(planeTransform); 625 626 // start with the whole surface at its current location 627 const Layer::State& s(layer->drawingState()); 628 629 /* 630 * opaqueRegion: area of a surface that is fully opaque. 631 */ 632 Region opaqueRegion; 633 634 /* 635 * visibleRegion: area of a surface that is visible on screen 636 * and not fully transparent. This is essentially the layer's 637 * footprint minus the opaque regions above it. 638 * Areas covered by a translucent surface are considered visible. 639 */ 640 Region visibleRegion; 641 642 /* 643 * coveredRegion: area of a surface that is covered by all 644 * visible regions above it (which includes the translucent areas). 645 */ 646 Region coveredRegion; 647 648 649 // handle hidden surfaces by setting the visible region to empty 650 if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { 651 const bool translucent = !layer->isOpaque(); 652 const Rect bounds(layer->visibleBounds()); 653 visibleRegion.set(bounds); 654 visibleRegion.andSelf(screenRegion); 655 if (!visibleRegion.isEmpty()) { 656 // Remove the transparent area from the visible region 657 if (translucent) { 658 visibleRegion.subtractSelf(layer->transparentRegionScreen); 659 } 660 661 // compute the opaque region 662 const int32_t layerOrientation = layer->getOrientation(); 663 if (s.alpha==255 && !translucent && 664 ((layerOrientation & Transform::ROT_INVALID) == false)) { 665 // the opaque region is the layer's footprint 666 opaqueRegion = visibleRegion; 667 } 668 } 669 } 670 671 // Clip the covered region to the visible region 672 coveredRegion = aboveCoveredLayers.intersect(visibleRegion); 673 674 // Update aboveCoveredLayers for next (lower) layer 675 aboveCoveredLayers.orSelf(visibleRegion); 676 677 // subtract the opaque region covered by the layers above us 678 visibleRegion.subtractSelf(aboveOpaqueLayers); 679 680 // compute this layer's dirty region 681 if (layer->contentDirty) { 682 // we need to invalidate the whole region 683 dirty = visibleRegion; 684 // as well, as the old visible region 685 dirty.orSelf(layer->visibleRegionScreen); 686 layer->contentDirty = false; 687 } else { 688 /* compute the exposed region: 689 * the exposed region consists of two components: 690 * 1) what's VISIBLE now and was COVERED before 691 * 2) what's EXPOSED now less what was EXPOSED before 692 * 693 * note that (1) is conservative, we start with the whole 694 * visible region but only keep what used to be covered by 695 * something -- which mean it may have been exposed. 696 * 697 * (2) handles areas that were not covered by anything but got 698 * exposed because of a resize. 699 */ 700 const Region newExposed = visibleRegion - coveredRegion; 701 const Region oldVisibleRegion = layer->visibleRegionScreen; 702 const Region oldCoveredRegion = layer->coveredRegionScreen; 703 const Region oldExposed = oldVisibleRegion - oldCoveredRegion; 704 dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); 705 } 706 dirty.subtractSelf(aboveOpaqueLayers); 707 708 // accumulate to the screen dirty region 709 dirtyRegion.orSelf(dirty); 710 711 // Update aboveOpaqueLayers for next (lower) layer 712 aboveOpaqueLayers.orSelf(opaqueRegion); 713 714 // Store the visible region is screen space 715 layer->setVisibleRegion(visibleRegion); 716 layer->setCoveredRegion(coveredRegion); 717 718 // If a secure layer is partially visible, lock-down the screen! 719 if (layer->isSecure() && !visibleRegion.isEmpty()) { 720 secureFrameBuffer = true; 721 } 722 } 723 724 // invalidate the areas where a layer was removed 725 dirtyRegion.orSelf(mDirtyRegionRemovedLayer); 726 mDirtyRegionRemovedLayer.clear(); 727 728 mSecureFrameBuffer = secureFrameBuffer; 729 opaqueRegion = aboveOpaqueLayers; 730} 731 732 733void SurfaceFlinger::commitTransaction() 734{ 735 mDrawingState = mCurrentState; 736 mResizeTransationPending = false; 737 mTransactionCV.broadcast(); 738} 739 740void SurfaceFlinger::handlePageFlip() 741{ 742 bool visibleRegions = mVisibleRegionsDirty; 743 const LayerVector& currentLayers(mDrawingState.layersSortedByZ); 744 visibleRegions |= lockPageFlip(currentLayers); 745 746 const DisplayHardware& hw = graphicPlane(0).displayHardware(); 747 const Region screenRegion(hw.bounds()); 748 if (visibleRegions) { 749 Region opaqueRegion; 750 computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion); 751 752 /* 753 * rebuild the visible layer list 754 */ 755 const size_t count = currentLayers.size(); 756 mVisibleLayersSortedByZ.clear(); 757 mVisibleLayersSortedByZ.setCapacity(count); 758 for (size_t i=0 ; i<count ; i++) { 759 if (!currentLayers[i]->visibleRegionScreen.isEmpty()) 760 mVisibleLayersSortedByZ.add(currentLayers[i]); 761 } 762 763 mWormholeRegion = screenRegion.subtract(opaqueRegion); 764 mVisibleRegionsDirty = false; 765 invalidateHwcGeometry(); 766 } 767 768 unlockPageFlip(currentLayers); 769 mDirtyRegion.andSelf(screenRegion); 770} 771 772void SurfaceFlinger::invalidateHwcGeometry() 773{ 774 mHwWorkListDirty = true; 775} 776 777bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers) 778{ 779 bool recomputeVisibleRegions = false; 780 size_t count = currentLayers.size(); 781 sp<LayerBase> const* layers = currentLayers.array(); 782 for (size_t i=0 ; i<count ; i++) { 783 const sp<LayerBase>& layer(layers[i]); 784 layer->lockPageFlip(recomputeVisibleRegions); 785 } 786 return recomputeVisibleRegions; 787} 788 789void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers) 790{ 791 const GraphicPlane& plane(graphicPlane(0)); 792 const Transform& planeTransform(plane.transform()); 793 size_t count = currentLayers.size(); 794 sp<LayerBase> const* layers = currentLayers.array(); 795 for (size_t i=0 ; i<count ; i++) { 796 const sp<LayerBase>& layer(layers[i]); 797 layer->unlockPageFlip(planeTransform, mDirtyRegion); 798 } 799} 800 801void SurfaceFlinger::handleWorkList() 802{ 803 mHwWorkListDirty = false; 804 HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer()); 805 if (hwc.initCheck() == NO_ERROR) { 806 const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); 807 const size_t count = currentLayers.size(); 808 hwc.createWorkList(count); 809 hwc_layer_t* const cur(hwc.getLayers()); 810 for (size_t i=0 ; cur && i<count ; i++) { 811 currentLayers[i]->setGeometry(&cur[i]); 812 if (mDebugDisableHWC) { 813 cur[i].compositionType = HWC_FRAMEBUFFER; 814 cur[i].flags |= HWC_SKIP_LAYER; 815 } 816 } 817 } 818} 819 820void SurfaceFlinger::handleRepaint() 821{ 822 // compute the invalid region 823 mInvalidRegion.orSelf(mDirtyRegion); 824 825 if (UNLIKELY(mDebugRegion)) { 826 debugFlashRegions(); 827 } 828 829 // set the frame buffer 830 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 831 glMatrixMode(GL_MODELVIEW); 832 glLoadIdentity(); 833 834 uint32_t flags = hw.getFlags(); 835 if ((flags & DisplayHardware::SWAP_RECTANGLE) || 836 (flags & DisplayHardware::BUFFER_PRESERVED)) 837 { 838 // we can redraw only what's dirty, but since SWAP_RECTANGLE only 839 // takes a rectangle, we must make sure to update that whole 840 // rectangle in that case 841 if (flags & DisplayHardware::SWAP_RECTANGLE) { 842 // TODO: we really should be able to pass a region to 843 // SWAP_RECTANGLE so that we don't have to redraw all this. 844 mDirtyRegion.set(mInvalidRegion.bounds()); 845 } else { 846 // in the BUFFER_PRESERVED case, obviously, we can update only 847 // what's needed and nothing more. 848 // NOTE: this is NOT a common case, as preserving the backbuffer 849 // is costly and usually involves copying the whole update back. 850 } 851 } else { 852 if (flags & DisplayHardware::PARTIAL_UPDATES) { 853 // We need to redraw the rectangle that will be updated 854 // (pushed to the framebuffer). 855 // This is needed because PARTIAL_UPDATES only takes one 856 // rectangle instead of a region (see DisplayHardware::flip()) 857 mDirtyRegion.set(mInvalidRegion.bounds()); 858 } else { 859 // we need to redraw everything (the whole screen) 860 mDirtyRegion.set(hw.bounds()); 861 mInvalidRegion = mDirtyRegion; 862 } 863 } 864 865 // compose all surfaces 866 composeSurfaces(mDirtyRegion); 867 868 // clear the dirty regions 869 mDirtyRegion.clear(); 870} 871 872void SurfaceFlinger::composeSurfaces(const Region& dirty) 873{ 874 if (UNLIKELY(!mWormholeRegion.isEmpty())) { 875 // should never happen unless the window manager has a bug 876 // draw something... 877 drawWormhole(); 878 } 879 880 status_t err = NO_ERROR; 881 const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 882 size_t count = layers.size(); 883 884 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 885 HWComposer& hwc(hw.getHwComposer()); 886 hwc_layer_t* const cur(hwc.getLayers()); 887 888 LOGE_IF(cur && hwc.getNumLayers() != count, 889 "HAL number of layers (%d) doesn't match surfaceflinger (%d)", 890 hwc.getNumLayers(), count); 891 892 // just to be extra-safe, use the smallest count 893 if (hwc.initCheck() == NO_ERROR) { 894 count = count < hwc.getNumLayers() ? count : hwc.getNumLayers(); 895 } 896 897 /* 898 * update the per-frame h/w composer data for each layer 899 * and build the transparent region of the FB 900 */ 901 Region transparent; 902 if (cur) { 903 for (size_t i=0 ; i<count ; i++) { 904 const sp<LayerBase>& layer(layers[i]); 905 layer->setPerFrameData(&cur[i]); 906 } 907 err = hwc.prepare(); 908 LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); 909 910 if (err == NO_ERROR) { 911 for (size_t i=0 ; i<count ; i++) { 912 if (cur[i].hints & HWC_HINT_CLEAR_FB) { 913 const sp<LayerBase>& layer(layers[i]); 914 if (layer->isOpaque()) { 915 transparent.orSelf(layer->visibleRegionScreen); 916 } 917 } 918 } 919 920 /* 921 * clear the area of the FB that need to be transparent 922 */ 923 transparent.andSelf(dirty); 924 if (!transparent.isEmpty()) { 925 glClearColor(0,0,0,0); 926 Region::const_iterator it = transparent.begin(); 927 Region::const_iterator const end = transparent.end(); 928 const int32_t height = hw.getHeight(); 929 while (it != end) { 930 const Rect& r(*it++); 931 const GLint sy = height - (r.top + r.height()); 932 glScissor(r.left, sy, r.width(), r.height()); 933 glClear(GL_COLOR_BUFFER_BIT); 934 } 935 } 936 } 937 } 938 939 940 /* 941 * and then, render the layers targeted at the framebuffer 942 */ 943 for (size_t i=0 ; i<count ; i++) { 944 if (cur) { 945 if ((cur[i].compositionType != HWC_FRAMEBUFFER) && 946 !(cur[i].flags & HWC_SKIP_LAYER)) { 947 // skip layers handled by the HAL 948 continue; 949 } 950 } 951 952 const sp<LayerBase>& layer(layers[i]); 953 const Region clip(dirty.intersect(layer->visibleRegionScreen)); 954 if (!clip.isEmpty()) { 955 layer->draw(clip); 956 } 957 } 958} 959 960void SurfaceFlinger::debugFlashRegions() 961{ 962 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 963 const uint32_t flags = hw.getFlags(); 964 965 if (!((flags & DisplayHardware::SWAP_RECTANGLE) || 966 (flags & DisplayHardware::BUFFER_PRESERVED))) { 967 const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ? 968 mDirtyRegion.bounds() : hw.bounds()); 969 composeSurfaces(repaint); 970 } 971 972 glDisable(GL_BLEND); 973 glDisable(GL_DITHER); 974 glDisable(GL_SCISSOR_TEST); 975 976 static int toggle = 0; 977 toggle = 1 - toggle; 978 if (toggle) { 979 glColor4f(1, 0, 1, 1); 980 } else { 981 glColor4f(1, 1, 0, 1); 982 } 983 984 Region::const_iterator it = mDirtyRegion.begin(); 985 Region::const_iterator const end = mDirtyRegion.end(); 986 while (it != end) { 987 const Rect& r = *it++; 988 GLfloat vertices[][2] = { 989 { r.left, r.top }, 990 { r.left, r.bottom }, 991 { r.right, r.bottom }, 992 { r.right, r.top } 993 }; 994 glVertexPointer(2, GL_FLOAT, 0, vertices); 995 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 996 } 997 998 if (mInvalidRegion.isEmpty()) { 999 mDirtyRegion.dump("mDirtyRegion"); 1000 mInvalidRegion.dump("mInvalidRegion"); 1001 } 1002 hw.flip(mInvalidRegion); 1003 1004 if (mDebugRegion > 1) 1005 usleep(mDebugRegion * 1000); 1006 1007 glEnable(GL_SCISSOR_TEST); 1008 //mDirtyRegion.dump("mDirtyRegion"); 1009} 1010 1011void SurfaceFlinger::drawWormhole() const 1012{ 1013 const Region region(mWormholeRegion.intersect(mDirtyRegion)); 1014 if (region.isEmpty()) 1015 return; 1016 1017 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1018 const int32_t width = hw.getWidth(); 1019 const int32_t height = hw.getHeight(); 1020 1021 glDisable(GL_BLEND); 1022 glDisable(GL_DITHER); 1023 1024 if (LIKELY(!mDebugBackground)) { 1025 glClearColor(0,0,0,0); 1026 Region::const_iterator it = region.begin(); 1027 Region::const_iterator const end = region.end(); 1028 while (it != end) { 1029 const Rect& r = *it++; 1030 const GLint sy = height - (r.top + r.height()); 1031 glScissor(r.left, sy, r.width(), r.height()); 1032 glClear(GL_COLOR_BUFFER_BIT); 1033 } 1034 } else { 1035 const GLshort vertices[][2] = { { 0, 0 }, { width, 0 }, 1036 { width, height }, { 0, height } }; 1037 const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } }; 1038 glVertexPointer(2, GL_SHORT, 0, vertices); 1039 glTexCoordPointer(2, GL_SHORT, 0, tcoords); 1040 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1041#if defined(GL_OES_EGL_image_external) 1042 if (GLExtensions::getInstance().haveTextureExternal()) { 1043 glDisable(GL_TEXTURE_EXTERNAL_OES); 1044 } 1045#endif 1046 glEnable(GL_TEXTURE_2D); 1047 glBindTexture(GL_TEXTURE_2D, mWormholeTexName); 1048 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1049 glMatrixMode(GL_TEXTURE); 1050 glLoadIdentity(); 1051 glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1); 1052 Region::const_iterator it = region.begin(); 1053 Region::const_iterator const end = region.end(); 1054 while (it != end) { 1055 const Rect& r = *it++; 1056 const GLint sy = height - (r.top + r.height()); 1057 glScissor(r.left, sy, r.width(), r.height()); 1058 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1059 } 1060 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1061 glDisable(GL_TEXTURE_2D); 1062 glLoadIdentity(); 1063 glMatrixMode(GL_MODELVIEW); 1064 } 1065} 1066 1067void SurfaceFlinger::debugShowFPS() const 1068{ 1069 static int mFrameCount; 1070 static int mLastFrameCount = 0; 1071 static nsecs_t mLastFpsTime = 0; 1072 static float mFps = 0; 1073 mFrameCount++; 1074 nsecs_t now = systemTime(); 1075 nsecs_t diff = now - mLastFpsTime; 1076 if (diff > ms2ns(250)) { 1077 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 1078 mLastFpsTime = now; 1079 mLastFrameCount = mFrameCount; 1080 } 1081 // XXX: mFPS has the value we want 1082 } 1083 1084status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer) 1085{ 1086 Mutex::Autolock _l(mStateLock); 1087 addLayer_l(layer); 1088 setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1089 return NO_ERROR; 1090} 1091 1092status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer) 1093{ 1094 ssize_t i = mCurrentState.layersSortedByZ.add(layer); 1095 return (i < 0) ? status_t(i) : status_t(NO_ERROR); 1096} 1097 1098ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, 1099 const sp<LayerBaseClient>& lbc) 1100{ 1101 // attach this layer to the client 1102 size_t name = client->attachLayer(lbc); 1103 1104 Mutex::Autolock _l(mStateLock); 1105 1106 // add this layer to the current state list 1107 addLayer_l(lbc); 1108 1109 return ssize_t(name); 1110} 1111 1112status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer) 1113{ 1114 Mutex::Autolock _l(mStateLock); 1115 status_t err = purgatorizeLayer_l(layer); 1116 if (err == NO_ERROR) 1117 setTransactionFlags(eTransactionNeeded); 1118 return err; 1119} 1120 1121status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase) 1122{ 1123 sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient()); 1124 if (lbc != 0) { 1125 mLayerMap.removeItem( lbc->getSurfaceBinder() ); 1126 } 1127 ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase); 1128 if (index >= 0) { 1129 mLayersRemoved = true; 1130 return NO_ERROR; 1131 } 1132 return status_t(index); 1133} 1134 1135status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase) 1136{ 1137 // First add the layer to the purgatory list, which makes sure it won't 1138 // go away, then remove it from the main list (through a transaction). 1139 ssize_t err = removeLayer_l(layerBase); 1140 if (err >= 0) { 1141 mLayerPurgatory.add(layerBase); 1142 } 1143 1144 layerBase->onRemoved(); 1145 1146 // it's possible that we don't find a layer, because it might 1147 // have been destroyed already -- this is not technically an error 1148 // from the user because there is a race between Client::destroySurface(), 1149 // ~Client() and ~ISurface(). 1150 return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err; 1151} 1152 1153status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer) 1154{ 1155 layer->forceVisibilityTransaction(); 1156 setTransactionFlags(eTraversalNeeded); 1157 return NO_ERROR; 1158} 1159 1160uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) 1161{ 1162 return android_atomic_release_load(&mTransactionFlags); 1163} 1164 1165uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) 1166{ 1167 return android_atomic_and(~flags, &mTransactionFlags) & flags; 1168} 1169 1170uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) 1171{ 1172 uint32_t old = android_atomic_or(flags, &mTransactionFlags); 1173 if ((old & flags)==0) { // wake the server up 1174 signalEvent(); 1175 } 1176 return old; 1177} 1178 1179void SurfaceFlinger::openGlobalTransaction() 1180{ 1181 android_atomic_inc(&mTransactionCount); 1182} 1183 1184void SurfaceFlinger::closeGlobalTransaction() 1185{ 1186 if (android_atomic_dec(&mTransactionCount) == 1) { 1187 signalEvent(); 1188 1189 // if there is a transaction with a resize, wait for it to 1190 // take effect before returning. 1191 Mutex::Autolock _l(mStateLock); 1192 while (mResizeTransationPending) { 1193 status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); 1194 if (CC_UNLIKELY(err != NO_ERROR)) { 1195 // just in case something goes wrong in SF, return to the 1196 // called after a few seconds. 1197 LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!"); 1198 mResizeTransationPending = false; 1199 break; 1200 } 1201 } 1202 } 1203} 1204 1205status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags) 1206{ 1207 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1208 return BAD_VALUE; 1209 1210 Mutex::Autolock _l(mStateLock); 1211 mCurrentState.freezeDisplay = 1; 1212 setTransactionFlags(eTransactionNeeded); 1213 1214 // flags is intended to communicate some sort of animation behavior 1215 // (for instance fading) 1216 return NO_ERROR; 1217} 1218 1219status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags) 1220{ 1221 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1222 return BAD_VALUE; 1223 1224 Mutex::Autolock _l(mStateLock); 1225 mCurrentState.freezeDisplay = 0; 1226 setTransactionFlags(eTransactionNeeded); 1227 1228 // flags is intended to communicate some sort of animation behavior 1229 // (for instance fading) 1230 return NO_ERROR; 1231} 1232 1233int SurfaceFlinger::setOrientation(DisplayID dpy, 1234 int orientation, uint32_t flags) 1235{ 1236 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 1237 return BAD_VALUE; 1238 1239 Mutex::Autolock _l(mStateLock); 1240 if (mCurrentState.orientation != orientation) { 1241 if (uint32_t(orientation)<=eOrientation270 || orientation==42) { 1242 mCurrentState.orientationType = flags; 1243 mCurrentState.orientation = orientation; 1244 setTransactionFlags(eTransactionNeeded); 1245 mTransactionCV.wait(mStateLock); 1246 } else { 1247 orientation = BAD_VALUE; 1248 } 1249 } 1250 return orientation; 1251} 1252 1253sp<ISurface> SurfaceFlinger::createSurface( 1254 ISurfaceComposerClient::surface_data_t* params, 1255 const String8& name, 1256 const sp<Client>& client, 1257 DisplayID d, uint32_t w, uint32_t h, PixelFormat format, 1258 uint32_t flags) 1259{ 1260 sp<LayerBaseClient> layer; 1261 sp<ISurface> surfaceHandle; 1262 1263 if (int32_t(w|h) < 0) { 1264 LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)", 1265 int(w), int(h)); 1266 return surfaceHandle; 1267 } 1268 1269 //LOGD("createSurface for pid %d (%d x %d)", pid, w, h); 1270 sp<Layer> normalLayer; 1271 switch (flags & eFXSurfaceMask) { 1272 case eFXSurfaceNormal: 1273 normalLayer = createNormalSurface(client, d, w, h, flags, format); 1274 layer = normalLayer; 1275 break; 1276 case eFXSurfaceBlur: 1277 // for now we treat Blur as Dim, until we can implement it 1278 // efficiently. 1279 case eFXSurfaceDim: 1280 layer = createDimSurface(client, d, w, h, flags); 1281 break; 1282 } 1283 1284 if (layer != 0) { 1285 layer->initStates(w, h, flags); 1286 layer->setName(name); 1287 ssize_t token = addClientLayer(client, layer); 1288 1289 surfaceHandle = layer->getSurface(); 1290 if (surfaceHandle != 0) { 1291 params->token = token; 1292 params->identity = layer->getIdentity(); 1293 params->width = w; 1294 params->height = h; 1295 params->format = format; 1296 if (normalLayer != 0) { 1297 Mutex::Autolock _l(mStateLock); 1298 mLayerMap.add(layer->getSurfaceBinder(), normalLayer); 1299 } 1300 } 1301 1302 setTransactionFlags(eTransactionNeeded); 1303 } 1304 1305 return surfaceHandle; 1306} 1307 1308sp<Layer> SurfaceFlinger::createNormalSurface( 1309 const sp<Client>& client, DisplayID display, 1310 uint32_t w, uint32_t h, uint32_t flags, 1311 PixelFormat& format) 1312{ 1313 // initialize the surfaces 1314 switch (format) { // TODO: take h/w into account 1315 case PIXEL_FORMAT_TRANSPARENT: 1316 case PIXEL_FORMAT_TRANSLUCENT: 1317 format = PIXEL_FORMAT_RGBA_8888; 1318 break; 1319 case PIXEL_FORMAT_OPAQUE: 1320#ifdef NO_RGBX_8888 1321 format = PIXEL_FORMAT_RGB_565; 1322#else 1323 format = PIXEL_FORMAT_RGBX_8888; 1324#endif 1325 break; 1326 } 1327 1328#ifdef NO_RGBX_8888 1329 if (format == PIXEL_FORMAT_RGBX_8888) 1330 format = PIXEL_FORMAT_RGBA_8888; 1331#endif 1332 1333 sp<Layer> layer = new Layer(this, display, client); 1334 status_t err = layer->setBuffers(w, h, format, flags); 1335 if (LIKELY(err != NO_ERROR)) { 1336 LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err)); 1337 layer.clear(); 1338 } 1339 return layer; 1340} 1341 1342sp<LayerDim> SurfaceFlinger::createDimSurface( 1343 const sp<Client>& client, DisplayID display, 1344 uint32_t w, uint32_t h, uint32_t flags) 1345{ 1346 sp<LayerDim> layer = new LayerDim(this, display, client); 1347 layer->initStates(w, h, flags); 1348 return layer; 1349} 1350 1351status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid) 1352{ 1353 /* 1354 * called by the window manager, when a surface should be marked for 1355 * destruction. 1356 * 1357 * The surface is removed from the current and drawing lists, but placed 1358 * in the purgatory queue, so it's not destroyed right-away (we need 1359 * to wait for all client's references to go away first). 1360 */ 1361 1362 status_t err = NAME_NOT_FOUND; 1363 Mutex::Autolock _l(mStateLock); 1364 sp<LayerBaseClient> layer = client->getLayerUser(sid); 1365 if (layer != 0) { 1366 err = purgatorizeLayer_l(layer); 1367 if (err == NO_ERROR) { 1368 setTransactionFlags(eTransactionNeeded); 1369 } 1370 } 1371 return err; 1372} 1373 1374status_t SurfaceFlinger::destroySurface(const wp<LayerBaseClient>& layer) 1375{ 1376 // called by ~ISurface() when all references are gone 1377 status_t err = NO_ERROR; 1378 sp<LayerBaseClient> l(layer.promote()); 1379 if (l != NULL) { 1380 Mutex::Autolock _l(mStateLock); 1381 err = removeLayer_l(l); 1382 if (err == NAME_NOT_FOUND) { 1383 // The surface wasn't in the current list, which means it was 1384 // removed already, which means it is in the purgatory, 1385 // and need to be removed from there. 1386 ssize_t idx = mLayerPurgatory.remove(l); 1387 LOGE_IF(idx < 0, 1388 "layer=%p is not in the purgatory list", l.get()); 1389 } 1390 LOGE_IF(err<0 && err != NAME_NOT_FOUND, 1391 "error removing layer=%p (%s)", l.get(), strerror(-err)); 1392 } 1393 return err; 1394} 1395 1396status_t SurfaceFlinger::setClientState( 1397 const sp<Client>& client, 1398 int32_t count, 1399 const layer_state_t* states) 1400{ 1401 Mutex::Autolock _l(mStateLock); 1402 uint32_t flags = 0; 1403 for (int i=0 ; i<count ; i++) { 1404 const layer_state_t& s(states[i]); 1405 sp<LayerBaseClient> layer(client->getLayerUser(s.surface)); 1406 if (layer != 0) { 1407 const uint32_t what = s.what; 1408 if (what & ePositionChanged) { 1409 if (layer->setPosition(s.x, s.y)) 1410 flags |= eTraversalNeeded; 1411 } 1412 if (what & eLayerChanged) { 1413 ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); 1414 if (layer->setLayer(s.z)) { 1415 mCurrentState.layersSortedByZ.removeAt(idx); 1416 mCurrentState.layersSortedByZ.add(layer); 1417 // we need traversal (state changed) 1418 // AND transaction (list changed) 1419 flags |= eTransactionNeeded|eTraversalNeeded; 1420 } 1421 } 1422 if (what & eSizeChanged) { 1423 if (layer->setSize(s.w, s.h)) { 1424 flags |= eTraversalNeeded; 1425 mResizeTransationPending = true; 1426 } 1427 } 1428 if (what & eAlphaChanged) { 1429 if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f))) 1430 flags |= eTraversalNeeded; 1431 } 1432 if (what & eMatrixChanged) { 1433 if (layer->setMatrix(s.matrix)) 1434 flags |= eTraversalNeeded; 1435 } 1436 if (what & eTransparentRegionChanged) { 1437 if (layer->setTransparentRegionHint(s.transparentRegion)) 1438 flags |= eTraversalNeeded; 1439 } 1440 if (what & eVisibilityChanged) { 1441 if (layer->setFlags(s.flags, s.mask)) 1442 flags |= eTraversalNeeded; 1443 } 1444 } 1445 } 1446 if (flags) { 1447 setTransactionFlags(flags); 1448 } 1449 return NO_ERROR; 1450} 1451 1452void SurfaceFlinger::screenReleased(int dpy) 1453{ 1454 // this may be called by a signal handler, we can't do too much in here 1455 android_atomic_or(eConsoleReleased, &mConsoleSignals); 1456 signalEvent(); 1457} 1458 1459void SurfaceFlinger::screenAcquired(int dpy) 1460{ 1461 // this may be called by a signal handler, we can't do too much in here 1462 android_atomic_or(eConsoleAcquired, &mConsoleSignals); 1463 signalEvent(); 1464} 1465 1466status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 1467{ 1468 const size_t SIZE = 4096; 1469 char buffer[SIZE]; 1470 String8 result; 1471 1472 if (!PermissionCache::checkCallingPermission(sDump)) { 1473 snprintf(buffer, SIZE, "Permission Denial: " 1474 "can't dump SurfaceFlinger from pid=%d, uid=%d\n", 1475 IPCThreadState::self()->getCallingPid(), 1476 IPCThreadState::self()->getCallingUid()); 1477 result.append(buffer); 1478 } else { 1479 1480 // figure out if we're stuck somewhere 1481 const nsecs_t now = systemTime(); 1482 const nsecs_t inSwapBuffers(mDebugInSwapBuffers); 1483 const nsecs_t inTransaction(mDebugInTransaction); 1484 nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0; 1485 nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0; 1486 1487 // Try to get the main lock, but don't insist if we can't 1488 // (this would indicate SF is stuck, but we want to be able to 1489 // print something in dumpsys). 1490 int retry = 3; 1491 while (mStateLock.tryLock()<0 && --retry>=0) { 1492 usleep(1000000); 1493 } 1494 const bool locked(retry >= 0); 1495 if (!locked) { 1496 snprintf(buffer, SIZE, 1497 "SurfaceFlinger appears to be unresponsive, " 1498 "dumping anyways (no locks held)\n"); 1499 result.append(buffer); 1500 } 1501 1502 /* 1503 * Dump the visible layer list 1504 */ 1505 const LayerVector& currentLayers = mCurrentState.layersSortedByZ; 1506 const size_t count = currentLayers.size(); 1507 snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count); 1508 result.append(buffer); 1509 for (size_t i=0 ; i<count ; i++) { 1510 const sp<LayerBase>& layer(currentLayers[i]); 1511 layer->dump(result, buffer, SIZE); 1512 const Layer::State& s(layer->drawingState()); 1513 s.transparentRegion.dump(result, "transparentRegion"); 1514 layer->transparentRegionScreen.dump(result, "transparentRegionScreen"); 1515 layer->visibleRegionScreen.dump(result, "visibleRegionScreen"); 1516 } 1517 1518 /* 1519 * Dump the layers in the purgatory 1520 */ 1521 1522 const size_t purgatorySize = mLayerPurgatory.size(); 1523 snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize); 1524 result.append(buffer); 1525 for (size_t i=0 ; i<purgatorySize ; i++) { 1526 const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i)); 1527 layer->shortDump(result, buffer, SIZE); 1528 } 1529 1530 /* 1531 * Dump SurfaceFlinger global state 1532 */ 1533 1534 snprintf(buffer, SIZE, "SurfaceFlinger global state\n"); 1535 result.append(buffer); 1536 mWormholeRegion.dump(result, "WormholeRegion"); 1537 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1538 snprintf(buffer, SIZE, 1539 " display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n", 1540 mFreezeDisplay?"yes":"no", mFreezeCount, 1541 mCurrentState.orientation, hw.canDraw()); 1542 result.append(buffer); 1543 snprintf(buffer, SIZE, 1544 " last eglSwapBuffers() time: %f us\n" 1545 " last transaction time : %f us\n", 1546 mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0); 1547 result.append(buffer); 1548 1549 if (inSwapBuffersDuration || !locked) { 1550 snprintf(buffer, SIZE, " eglSwapBuffers time: %f us\n", 1551 inSwapBuffersDuration/1000.0); 1552 result.append(buffer); 1553 } 1554 1555 if (inTransactionDuration || !locked) { 1556 snprintf(buffer, SIZE, " transaction time: %f us\n", 1557 inTransactionDuration/1000.0); 1558 result.append(buffer); 1559 } 1560 1561 /* 1562 * Dump HWComposer state 1563 */ 1564 HWComposer& hwc(hw.getHwComposer()); 1565 snprintf(buffer, SIZE, " h/w composer %s and %s\n", 1566 hwc.initCheck()==NO_ERROR ? "present" : "not present", 1567 mDebugDisableHWC ? "disabled" : "enabled"); 1568 result.append(buffer); 1569 hwc.dump(result, buffer, SIZE); 1570 1571 /* 1572 * Dump gralloc state 1573 */ 1574 const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get()); 1575 alloc.dump(result); 1576 hw.dump(result); 1577 1578 if (locked) { 1579 mStateLock.unlock(); 1580 } 1581 } 1582 write(fd, result.string(), result.size()); 1583 return NO_ERROR; 1584} 1585 1586status_t SurfaceFlinger::onTransact( 1587 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1588{ 1589 switch (code) { 1590 case CREATE_CONNECTION: 1591 case OPEN_GLOBAL_TRANSACTION: 1592 case CLOSE_GLOBAL_TRANSACTION: 1593 case SET_ORIENTATION: 1594 case FREEZE_DISPLAY: 1595 case UNFREEZE_DISPLAY: 1596 case BOOT_FINISHED: 1597 case TURN_ELECTRON_BEAM_OFF: 1598 case TURN_ELECTRON_BEAM_ON: 1599 { 1600 // codes that require permission check 1601 IPCThreadState* ipc = IPCThreadState::self(); 1602 const int pid = ipc->getCallingPid(); 1603 const int uid = ipc->getCallingUid(); 1604 if ((uid != AID_GRAPHICS) && 1605 !PermissionCache::checkPermission(sAccessSurfaceFlinger, pid, uid)) { 1606 LOGE("Permission Denial: " 1607 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1608 return PERMISSION_DENIED; 1609 } 1610 break; 1611 } 1612 case CAPTURE_SCREEN: 1613 { 1614 // codes that require permission check 1615 IPCThreadState* ipc = IPCThreadState::self(); 1616 const int pid = ipc->getCallingPid(); 1617 const int uid = ipc->getCallingUid(); 1618 if ((uid != AID_GRAPHICS) && 1619 !PermissionCache::checkPermission(sReadFramebuffer, pid, uid)) { 1620 LOGE("Permission Denial: " 1621 "can't read framebuffer pid=%d, uid=%d", pid, uid); 1622 return PERMISSION_DENIED; 1623 } 1624 break; 1625 } 1626 } 1627 1628 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); 1629 if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { 1630 CHECK_INTERFACE(ISurfaceComposer, data, reply); 1631 if (UNLIKELY(!PermissionCache::checkCallingPermission(sHardwareTest))) { 1632 IPCThreadState* ipc = IPCThreadState::self(); 1633 const int pid = ipc->getCallingPid(); 1634 const int uid = ipc->getCallingUid(); 1635 LOGE("Permission Denial: " 1636 "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid); 1637 return PERMISSION_DENIED; 1638 } 1639 int n; 1640 switch (code) { 1641 case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE 1642 case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE 1643 return NO_ERROR; 1644 case 1002: // SHOW_UPDATES 1645 n = data.readInt32(); 1646 mDebugRegion = n ? n : (mDebugRegion ? 0 : 1); 1647 return NO_ERROR; 1648 case 1003: // SHOW_BACKGROUND 1649 n = data.readInt32(); 1650 mDebugBackground = n ? 1 : 0; 1651 return NO_ERROR; 1652 case 1008: // toggle use of hw composer 1653 n = data.readInt32(); 1654 mDebugDisableHWC = n ? 1 : 0; 1655 invalidateHwcGeometry(); 1656 // fall-through... 1657 case 1004:{ // repaint everything 1658 Mutex::Autolock _l(mStateLock); 1659 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1660 mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe 1661 signalEvent(); 1662 return NO_ERROR; 1663 } 1664 case 1005:{ // force transaction 1665 setTransactionFlags(eTransactionNeeded|eTraversalNeeded); 1666 return NO_ERROR; 1667 } 1668 case 1006:{ // enable/disable GraphicLog 1669 int enabled = data.readInt32(); 1670 GraphicLog::getInstance().setEnabled(enabled); 1671 return NO_ERROR; 1672 } 1673 case 1007: // set mFreezeCount 1674 mFreezeCount = data.readInt32(); 1675 mFreezeDisplayTime = 0; 1676 return NO_ERROR; 1677 case 1010: // interrogate. 1678 reply->writeInt32(0); 1679 reply->writeInt32(0); 1680 reply->writeInt32(mDebugRegion); 1681 reply->writeInt32(mDebugBackground); 1682 return NO_ERROR; 1683 case 1013: { 1684 Mutex::Autolock _l(mStateLock); 1685 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1686 reply->writeInt32(hw.getPageFlipCount()); 1687 } 1688 return NO_ERROR; 1689 } 1690 } 1691 return err; 1692} 1693 1694// --------------------------------------------------------------------------- 1695 1696status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, 1697 GLuint* textureName, GLfloat* uOut, GLfloat* vOut) 1698{ 1699 if (!GLExtensions::getInstance().haveFramebufferObject()) 1700 return INVALID_OPERATION; 1701 1702 // get screen geometry 1703 const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 1704 const uint32_t hw_w = hw.getWidth(); 1705 const uint32_t hw_h = hw.getHeight(); 1706 GLfloat u = 1; 1707 GLfloat v = 1; 1708 1709 // make sure to clear all GL error flags 1710 while ( glGetError() != GL_NO_ERROR ) ; 1711 1712 // create a FBO 1713 GLuint name, tname; 1714 glGenTextures(1, &tname); 1715 glBindTexture(GL_TEXTURE_2D, tname); 1716 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1717 hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 1718 if (glGetError() != GL_NO_ERROR) { 1719 while ( glGetError() != GL_NO_ERROR ) ; 1720 GLint tw = (2 << (31 - clz(hw_w))); 1721 GLint th = (2 << (31 - clz(hw_h))); 1722 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1723 tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); 1724 u = GLfloat(hw_w) / tw; 1725 v = GLfloat(hw_h) / th; 1726 } 1727 glGenFramebuffersOES(1, &name); 1728 glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 1729 glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 1730 GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0); 1731 1732 // redraw the screen entirely... 1733 glClearColor(0,0,0,1); 1734 glClear(GL_COLOR_BUFFER_BIT); 1735 const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 1736 const size_t count = layers.size(); 1737 for (size_t i=0 ; i<count ; ++i) { 1738 const sp<LayerBase>& layer(layers[i]); 1739 layer->drawForSreenShot(); 1740 } 1741 1742 // back to main framebuffer 1743 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 1744 glDisable(GL_SCISSOR_TEST); 1745 glDeleteFramebuffersOES(1, &name); 1746 1747 *textureName = tname; 1748 *uOut = u; 1749 *vOut = v; 1750 return NO_ERROR; 1751} 1752 1753// --------------------------------------------------------------------------- 1754 1755status_t SurfaceFlinger::electronBeamOffAnimationImplLocked() 1756{ 1757 status_t result = PERMISSION_DENIED; 1758 1759 if (!GLExtensions::getInstance().haveFramebufferObject()) 1760 return INVALID_OPERATION; 1761 1762 // get screen geometry 1763 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1764 const uint32_t hw_w = hw.getWidth(); 1765 const uint32_t hw_h = hw.getHeight(); 1766 const Region screenBounds(hw.bounds()); 1767 1768 GLfloat u, v; 1769 GLuint tname; 1770 result = renderScreenToTextureLocked(0, &tname, &u, &v); 1771 if (result != NO_ERROR) { 1772 return result; 1773 } 1774 1775 GLfloat vtx[8]; 1776 const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 1777 glBindTexture(GL_TEXTURE_2D, tname); 1778 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 1779 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1780 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1781 glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 1782 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1783 glVertexPointer(2, GL_FLOAT, 0, vtx); 1784 1785 class s_curve_interpolator { 1786 const float nbFrames, s, v; 1787 public: 1788 s_curve_interpolator(int nbFrames, float s) 1789 : nbFrames(1.0f / (nbFrames-1)), s(s), 1790 v(1.0f + expf(-s + 0.5f*s)) { 1791 } 1792 float operator()(int f) { 1793 const float x = f * nbFrames; 1794 return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 1795 } 1796 }; 1797 1798 class v_stretch { 1799 const GLfloat hw_w, hw_h; 1800 public: 1801 v_stretch(uint32_t hw_w, uint32_t hw_h) 1802 : hw_w(hw_w), hw_h(hw_h) { 1803 } 1804 void operator()(GLfloat* vtx, float v) { 1805 const GLfloat w = hw_w + (hw_w * v); 1806 const GLfloat h = hw_h - (hw_h * v); 1807 const GLfloat x = (hw_w - w) * 0.5f; 1808 const GLfloat y = (hw_h - h) * 0.5f; 1809 vtx[0] = x; vtx[1] = y; 1810 vtx[2] = x; vtx[3] = y + h; 1811 vtx[4] = x + w; vtx[5] = y + h; 1812 vtx[6] = x + w; vtx[7] = y; 1813 } 1814 }; 1815 1816 class h_stretch { 1817 const GLfloat hw_w, hw_h; 1818 public: 1819 h_stretch(uint32_t hw_w, uint32_t hw_h) 1820 : hw_w(hw_w), hw_h(hw_h) { 1821 } 1822 void operator()(GLfloat* vtx, float v) { 1823 const GLfloat w = hw_w - (hw_w * v); 1824 const GLfloat h = 1.0f; 1825 const GLfloat x = (hw_w - w) * 0.5f; 1826 const GLfloat y = (hw_h - h) * 0.5f; 1827 vtx[0] = x; vtx[1] = y; 1828 vtx[2] = x; vtx[3] = y + h; 1829 vtx[4] = x + w; vtx[5] = y + h; 1830 vtx[6] = x + w; vtx[7] = y; 1831 } 1832 }; 1833 1834 // the full animation is 24 frames 1835 const int nbFrames = 12; 1836 s_curve_interpolator itr(nbFrames, 7.5f); 1837 s_curve_interpolator itg(nbFrames, 8.0f); 1838 s_curve_interpolator itb(nbFrames, 8.5f); 1839 1840 v_stretch vverts(hw_w, hw_h); 1841 glEnable(GL_BLEND); 1842 glBlendFunc(GL_ONE, GL_ONE); 1843 for (int i=0 ; i<nbFrames ; i++) { 1844 float x, y, w, h; 1845 const float vr = itr(i); 1846 const float vg = itg(i); 1847 const float vb = itb(i); 1848 1849 // clear screen 1850 glColorMask(1,1,1,1); 1851 glClear(GL_COLOR_BUFFER_BIT); 1852 glEnable(GL_TEXTURE_2D); 1853 1854 // draw the red plane 1855 vverts(vtx, vr); 1856 glColorMask(1,0,0,1); 1857 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1858 1859 // draw the green plane 1860 vverts(vtx, vg); 1861 glColorMask(0,1,0,1); 1862 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1863 1864 // draw the blue plane 1865 vverts(vtx, vb); 1866 glColorMask(0,0,1,1); 1867 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1868 1869 // draw the white highlight (we use the last vertices) 1870 glDisable(GL_TEXTURE_2D); 1871 glColorMask(1,1,1,1); 1872 glColor4f(vg, vg, vg, 1); 1873 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1874 hw.flip(screenBounds); 1875 } 1876 1877 h_stretch hverts(hw_w, hw_h); 1878 glDisable(GL_BLEND); 1879 glDisable(GL_TEXTURE_2D); 1880 glColorMask(1,1,1,1); 1881 for (int i=0 ; i<nbFrames ; i++) { 1882 const float v = itg(i); 1883 hverts(vtx, v); 1884 glClear(GL_COLOR_BUFFER_BIT); 1885 glColor4f(1-v, 1-v, 1-v, 1); 1886 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1887 hw.flip(screenBounds); 1888 } 1889 1890 glColorMask(1,1,1,1); 1891 glEnable(GL_SCISSOR_TEST); 1892 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1893 glDeleteTextures(1, &tname); 1894 glDisable(GL_TEXTURE_2D); 1895 return NO_ERROR; 1896} 1897 1898status_t SurfaceFlinger::electronBeamOnAnimationImplLocked() 1899{ 1900 status_t result = PERMISSION_DENIED; 1901 1902 if (!GLExtensions::getInstance().haveFramebufferObject()) 1903 return INVALID_OPERATION; 1904 1905 1906 // get screen geometry 1907 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 1908 const uint32_t hw_w = hw.getWidth(); 1909 const uint32_t hw_h = hw.getHeight(); 1910 const Region screenBounds(hw.bounds()); 1911 1912 GLfloat u, v; 1913 GLuint tname; 1914 result = renderScreenToTextureLocked(0, &tname, &u, &v); 1915 if (result != NO_ERROR) { 1916 return result; 1917 } 1918 1919 // back to main framebuffer 1920 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 1921 glDisable(GL_SCISSOR_TEST); 1922 1923 GLfloat vtx[8]; 1924 const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} }; 1925 glBindTexture(GL_TEXTURE_2D, tname); 1926 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 1927 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1928 glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1929 glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 1930 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1931 glVertexPointer(2, GL_FLOAT, 0, vtx); 1932 1933 class s_curve_interpolator { 1934 const float nbFrames, s, v; 1935 public: 1936 s_curve_interpolator(int nbFrames, float s) 1937 : nbFrames(1.0f / (nbFrames-1)), s(s), 1938 v(1.0f + expf(-s + 0.5f*s)) { 1939 } 1940 float operator()(int f) { 1941 const float x = f * nbFrames; 1942 return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f; 1943 } 1944 }; 1945 1946 class v_stretch { 1947 const GLfloat hw_w, hw_h; 1948 public: 1949 v_stretch(uint32_t hw_w, uint32_t hw_h) 1950 : hw_w(hw_w), hw_h(hw_h) { 1951 } 1952 void operator()(GLfloat* vtx, float v) { 1953 const GLfloat w = hw_w + (hw_w * v); 1954 const GLfloat h = hw_h - (hw_h * v); 1955 const GLfloat x = (hw_w - w) * 0.5f; 1956 const GLfloat y = (hw_h - h) * 0.5f; 1957 vtx[0] = x; vtx[1] = y; 1958 vtx[2] = x; vtx[3] = y + h; 1959 vtx[4] = x + w; vtx[5] = y + h; 1960 vtx[6] = x + w; vtx[7] = y; 1961 } 1962 }; 1963 1964 class h_stretch { 1965 const GLfloat hw_w, hw_h; 1966 public: 1967 h_stretch(uint32_t hw_w, uint32_t hw_h) 1968 : hw_w(hw_w), hw_h(hw_h) { 1969 } 1970 void operator()(GLfloat* vtx, float v) { 1971 const GLfloat w = hw_w - (hw_w * v); 1972 const GLfloat h = 1.0f; 1973 const GLfloat x = (hw_w - w) * 0.5f; 1974 const GLfloat y = (hw_h - h) * 0.5f; 1975 vtx[0] = x; vtx[1] = y; 1976 vtx[2] = x; vtx[3] = y + h; 1977 vtx[4] = x + w; vtx[5] = y + h; 1978 vtx[6] = x + w; vtx[7] = y; 1979 } 1980 }; 1981 1982 // the full animation is 12 frames 1983 int nbFrames = 8; 1984 s_curve_interpolator itr(nbFrames, 7.5f); 1985 s_curve_interpolator itg(nbFrames, 8.0f); 1986 s_curve_interpolator itb(nbFrames, 8.5f); 1987 1988 h_stretch hverts(hw_w, hw_h); 1989 glDisable(GL_BLEND); 1990 glDisable(GL_TEXTURE_2D); 1991 glColorMask(1,1,1,1); 1992 for (int i=nbFrames-1 ; i>=0 ; i--) { 1993 const float v = itg(i); 1994 hverts(vtx, v); 1995 glClear(GL_COLOR_BUFFER_BIT); 1996 glColor4f(1-v, 1-v, 1-v, 1); 1997 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 1998 hw.flip(screenBounds); 1999 } 2000 2001 nbFrames = 4; 2002 v_stretch vverts(hw_w, hw_h); 2003 glEnable(GL_BLEND); 2004 glBlendFunc(GL_ONE, GL_ONE); 2005 for (int i=nbFrames-1 ; i>=0 ; i--) { 2006 float x, y, w, h; 2007 const float vr = itr(i); 2008 const float vg = itg(i); 2009 const float vb = itb(i); 2010 2011 // clear screen 2012 glColorMask(1,1,1,1); 2013 glClear(GL_COLOR_BUFFER_BIT); 2014 glEnable(GL_TEXTURE_2D); 2015 2016 // draw the red plane 2017 vverts(vtx, vr); 2018 glColorMask(1,0,0,1); 2019 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2020 2021 // draw the green plane 2022 vverts(vtx, vg); 2023 glColorMask(0,1,0,1); 2024 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2025 2026 // draw the blue plane 2027 vverts(vtx, vb); 2028 glColorMask(0,0,1,1); 2029 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 2030 2031 hw.flip(screenBounds); 2032 } 2033 2034 glColorMask(1,1,1,1); 2035 glEnable(GL_SCISSOR_TEST); 2036 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 2037 glDeleteTextures(1, &tname); 2038 glDisable(GL_TEXTURE_2D); 2039 2040 return NO_ERROR; 2041} 2042 2043// --------------------------------------------------------------------------- 2044 2045status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode) 2046{ 2047 DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 2048 if (!hw.canDraw()) { 2049 // we're already off 2050 return NO_ERROR; 2051 } 2052 if (mode & ISurfaceComposer::eElectronBeamAnimationOff) { 2053 electronBeamOffAnimationImplLocked(); 2054 } 2055 2056 // always clear the whole screen at the end of the animation 2057 glClearColor(0,0,0,1); 2058 glDisable(GL_SCISSOR_TEST); 2059 glClear(GL_COLOR_BUFFER_BIT); 2060 glEnable(GL_SCISSOR_TEST); 2061 hw.flip( Region(hw.bounds()) ); 2062 2063 hw.setCanDraw(false); 2064 return NO_ERROR; 2065} 2066 2067status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode) 2068{ 2069 class MessageTurnElectronBeamOff : public MessageBase { 2070 SurfaceFlinger* flinger; 2071 int32_t mode; 2072 status_t result; 2073 public: 2074 MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode) 2075 : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 2076 } 2077 status_t getResult() const { 2078 return result; 2079 } 2080 virtual bool handler() { 2081 Mutex::Autolock _l(flinger->mStateLock); 2082 result = flinger->turnElectronBeamOffImplLocked(mode); 2083 return true; 2084 } 2085 }; 2086 2087 sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode); 2088 status_t res = postMessageSync(msg); 2089 if (res == NO_ERROR) { 2090 res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult(); 2091 2092 // work-around: when the power-manager calls us we activate the 2093 // animation. eventually, the "on" animation will be called 2094 // by the power-manager itself 2095 mElectronBeamAnimationMode = mode; 2096 } 2097 return res; 2098} 2099 2100// --------------------------------------------------------------------------- 2101 2102status_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode) 2103{ 2104 DisplayHardware& hw(graphicPlane(0).editDisplayHardware()); 2105 if (hw.canDraw()) { 2106 // we're already on 2107 return NO_ERROR; 2108 } 2109 if (mode & ISurfaceComposer::eElectronBeamAnimationOn) { 2110 electronBeamOnAnimationImplLocked(); 2111 } 2112 hw.setCanDraw(true); 2113 2114 // make sure to redraw the whole screen when the animation is done 2115 mDirtyRegion.set(hw.bounds()); 2116 signalEvent(); 2117 2118 return NO_ERROR; 2119} 2120 2121status_t SurfaceFlinger::turnElectronBeamOn(int32_t mode) 2122{ 2123 class MessageTurnElectronBeamOn : public MessageBase { 2124 SurfaceFlinger* flinger; 2125 int32_t mode; 2126 status_t result; 2127 public: 2128 MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode) 2129 : flinger(flinger), mode(mode), result(PERMISSION_DENIED) { 2130 } 2131 status_t getResult() const { 2132 return result; 2133 } 2134 virtual bool handler() { 2135 Mutex::Autolock _l(flinger->mStateLock); 2136 result = flinger->turnElectronBeamOnImplLocked(mode); 2137 return true; 2138 } 2139 }; 2140 2141 postMessageAsync( new MessageTurnElectronBeamOn(this, mode) ); 2142 return NO_ERROR; 2143} 2144 2145// --------------------------------------------------------------------------- 2146 2147status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, 2148 sp<IMemoryHeap>* heap, 2149 uint32_t* w, uint32_t* h, PixelFormat* f, 2150 uint32_t sw, uint32_t sh, 2151 uint32_t minLayerZ, uint32_t maxLayerZ) 2152{ 2153 status_t result = PERMISSION_DENIED; 2154 2155 // only one display supported for now 2156 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 2157 return BAD_VALUE; 2158 2159 // make sure none of the layers are protected 2160 const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); 2161 const size_t count = layers.size(); 2162 for (size_t i=0 ; i<count ; ++i) { 2163 const sp<LayerBase>& layer(layers[i]); 2164 const uint32_t z = layer->drawingState().z; 2165 if (z >= minLayerZ && z <= maxLayerZ) { 2166 if (layer->isProtected()) { 2167 return INVALID_OPERATION; 2168 } 2169 } 2170 } 2171 2172 if (!GLExtensions::getInstance().haveFramebufferObject()) 2173 return INVALID_OPERATION; 2174 2175 // get screen geometry 2176 const DisplayHardware& hw(graphicPlane(dpy).displayHardware()); 2177 const uint32_t hw_w = hw.getWidth(); 2178 const uint32_t hw_h = hw.getHeight(); 2179 2180 if ((sw > hw_w) || (sh > hw_h)) 2181 return BAD_VALUE; 2182 2183 sw = (!sw) ? hw_w : sw; 2184 sh = (!sh) ? hw_h : sh; 2185 const size_t size = sw * sh * 4; 2186 2187 //LOGD("screenshot: sw=%d, sh=%d, minZ=%d, maxZ=%d", 2188 // sw, sh, minLayerZ, maxLayerZ); 2189 2190 // make sure to clear all GL error flags 2191 while ( glGetError() != GL_NO_ERROR ) ; 2192 2193 // create a FBO 2194 GLuint name, tname; 2195 glGenRenderbuffersOES(1, &tname); 2196 glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname); 2197 glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh); 2198 glGenFramebuffersOES(1, &name); 2199 glBindFramebufferOES(GL_FRAMEBUFFER_OES, name); 2200 glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 2201 GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname); 2202 2203 GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 2204 2205 if (status == GL_FRAMEBUFFER_COMPLETE_OES) { 2206 2207 // invert everything, b/c glReadPixel() below will invert the FB 2208 glViewport(0, 0, sw, sh); 2209 glScissor(0, 0, sw, sh); 2210 glMatrixMode(GL_PROJECTION); 2211 glPushMatrix(); 2212 glLoadIdentity(); 2213 glOrthof(0, hw_w, 0, hw_h, 0, 1); 2214 glMatrixMode(GL_MODELVIEW); 2215 2216 // redraw the screen entirely... 2217 glClearColor(0,0,0,1); 2218 glClear(GL_COLOR_BUFFER_BIT); 2219 2220 for (size_t i=0 ; i<count ; ++i) { 2221 const sp<LayerBase>& layer(layers[i]); 2222 const uint32_t z = layer->drawingState().z; 2223 if (z >= minLayerZ && z <= maxLayerZ) { 2224 layer->drawForSreenShot(); 2225 } 2226 } 2227 2228 // XXX: this is needed on tegra 2229 glScissor(0, 0, sw, sh); 2230 2231 // check for errors and return screen capture 2232 if (glGetError() != GL_NO_ERROR) { 2233 // error while rendering 2234 result = INVALID_OPERATION; 2235 } else { 2236 // allocate shared memory large enough to hold the 2237 // screen capture 2238 sp<MemoryHeapBase> base( 2239 new MemoryHeapBase(size, 0, "screen-capture") ); 2240 void* const ptr = base->getBase(); 2241 if (ptr) { 2242 // capture the screen with glReadPixels() 2243 glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr); 2244 if (glGetError() == GL_NO_ERROR) { 2245 *heap = base; 2246 *w = sw; 2247 *h = sh; 2248 *f = PIXEL_FORMAT_RGBA_8888; 2249 result = NO_ERROR; 2250 } 2251 } else { 2252 result = NO_MEMORY; 2253 } 2254 } 2255 glEnable(GL_SCISSOR_TEST); 2256 glViewport(0, 0, hw_w, hw_h); 2257 glMatrixMode(GL_PROJECTION); 2258 glPopMatrix(); 2259 glMatrixMode(GL_MODELVIEW); 2260 } else { 2261 result = BAD_VALUE; 2262 } 2263 2264 // release FBO resources 2265 glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 2266 glDeleteRenderbuffersOES(1, &tname); 2267 glDeleteFramebuffersOES(1, &name); 2268 2269 hw.compositionComplete(); 2270 2271 // LOGD("screenshot: result = %s", result<0 ? strerror(result) : "OK"); 2272 2273 return result; 2274} 2275 2276 2277status_t SurfaceFlinger::captureScreen(DisplayID dpy, 2278 sp<IMemoryHeap>* heap, 2279 uint32_t* width, uint32_t* height, PixelFormat* format, 2280 uint32_t sw, uint32_t sh, 2281 uint32_t minLayerZ, uint32_t maxLayerZ) 2282{ 2283 // only one display supported for now 2284 if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) 2285 return BAD_VALUE; 2286 2287 if (!GLExtensions::getInstance().haveFramebufferObject()) 2288 return INVALID_OPERATION; 2289 2290 class MessageCaptureScreen : public MessageBase { 2291 SurfaceFlinger* flinger; 2292 DisplayID dpy; 2293 sp<IMemoryHeap>* heap; 2294 uint32_t* w; 2295 uint32_t* h; 2296 PixelFormat* f; 2297 uint32_t sw; 2298 uint32_t sh; 2299 uint32_t minLayerZ; 2300 uint32_t maxLayerZ; 2301 status_t result; 2302 public: 2303 MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy, 2304 sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f, 2305 uint32_t sw, uint32_t sh, 2306 uint32_t minLayerZ, uint32_t maxLayerZ) 2307 : flinger(flinger), dpy(dpy), 2308 heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), 2309 minLayerZ(minLayerZ), maxLayerZ(maxLayerZ), 2310 result(PERMISSION_DENIED) 2311 { 2312 } 2313 status_t getResult() const { 2314 return result; 2315 } 2316 virtual bool handler() { 2317 Mutex::Autolock _l(flinger->mStateLock); 2318 2319 // if we have secure windows, never allow the screen capture 2320 if (flinger->mSecureFrameBuffer) 2321 return true; 2322 2323 result = flinger->captureScreenImplLocked(dpy, 2324 heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); 2325 2326 return true; 2327 } 2328 }; 2329 2330 sp<MessageBase> msg = new MessageCaptureScreen(this, 2331 dpy, heap, width, height, format, sw, sh, minLayerZ, maxLayerZ); 2332 status_t res = postMessageSync(msg); 2333 if (res == NO_ERROR) { 2334 res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult(); 2335 } 2336 return res; 2337} 2338 2339// --------------------------------------------------------------------------- 2340 2341sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const 2342{ 2343 sp<Layer> result; 2344 Mutex::Autolock _l(mStateLock); 2345 result = mLayerMap.valueFor( sur->asBinder() ).promote(); 2346 return result; 2347} 2348 2349// --------------------------------------------------------------------------- 2350 2351Client::Client(const sp<SurfaceFlinger>& flinger) 2352 : mFlinger(flinger), mNameGenerator(1) 2353{ 2354} 2355 2356Client::~Client() 2357{ 2358 const size_t count = mLayers.size(); 2359 for (size_t i=0 ; i<count ; i++) { 2360 sp<LayerBaseClient> layer(mLayers.valueAt(i).promote()); 2361 if (layer != 0) { 2362 mFlinger->removeLayer(layer); 2363 } 2364 } 2365} 2366 2367status_t Client::initCheck() const { 2368 return NO_ERROR; 2369} 2370 2371size_t Client::attachLayer(const sp<LayerBaseClient>& layer) 2372{ 2373 Mutex::Autolock _l(mLock); 2374 size_t name = mNameGenerator++; 2375 mLayers.add(name, layer); 2376 return name; 2377} 2378 2379void Client::detachLayer(const LayerBaseClient* layer) 2380{ 2381 Mutex::Autolock _l(mLock); 2382 // we do a linear search here, because this doesn't happen often 2383 const size_t count = mLayers.size(); 2384 for (size_t i=0 ; i<count ; i++) { 2385 if (mLayers.valueAt(i) == layer) { 2386 mLayers.removeItemsAt(i, 1); 2387 break; 2388 } 2389 } 2390} 2391sp<LayerBaseClient> Client::getLayerUser(int32_t i) const 2392{ 2393 Mutex::Autolock _l(mLock); 2394 sp<LayerBaseClient> lbc; 2395 wp<LayerBaseClient> layer(mLayers.valueFor(i)); 2396 if (layer != 0) { 2397 lbc = layer.promote(); 2398 LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i)); 2399 } 2400 return lbc; 2401} 2402 2403 2404status_t Client::onTransact( 2405 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2406{ 2407 // these must be checked 2408 IPCThreadState* ipc = IPCThreadState::self(); 2409 const int pid = ipc->getCallingPid(); 2410 const int uid = ipc->getCallingUid(); 2411 const int self_pid = getpid(); 2412 if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) { 2413 // we're called from a different process, do the real check 2414 if (!PermissionCache::checkCallingPermission(sAccessSurfaceFlinger)) 2415 { 2416 LOGE("Permission Denial: " 2417 "can't openGlobalTransaction pid=%d, uid=%d", pid, uid); 2418 return PERMISSION_DENIED; 2419 } 2420 } 2421 return BnSurfaceComposerClient::onTransact(code, data, reply, flags); 2422} 2423 2424 2425sp<ISurface> Client::createSurface( 2426 ISurfaceComposerClient::surface_data_t* params, 2427 const String8& name, 2428 DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2429 uint32_t flags) 2430{ 2431 /* 2432 * createSurface must be called from the GL thread so that it can 2433 * have access to the GL context. 2434 */ 2435 2436 class MessageCreateSurface : public MessageBase { 2437 sp<ISurface> result; 2438 SurfaceFlinger* flinger; 2439 ISurfaceComposerClient::surface_data_t* params; 2440 Client* client; 2441 const String8& name; 2442 DisplayID display; 2443 uint32_t w, h; 2444 PixelFormat format; 2445 uint32_t flags; 2446 public: 2447 MessageCreateSurface(SurfaceFlinger* flinger, 2448 ISurfaceComposerClient::surface_data_t* params, 2449 const String8& name, Client* client, 2450 DisplayID display, uint32_t w, uint32_t h, PixelFormat format, 2451 uint32_t flags) 2452 : flinger(flinger), params(params), client(client), name(name), 2453 display(display), w(w), h(h), format(format), flags(flags) 2454 { 2455 } 2456 sp<ISurface> getResult() const { return result; } 2457 virtual bool handler() { 2458 result = flinger->createSurface(params, name, client, 2459 display, w, h, format, flags); 2460 return true; 2461 } 2462 }; 2463 2464 sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(), 2465 params, name, this, display, w, h, format, flags); 2466 mFlinger->postMessageSync(msg); 2467 return static_cast<MessageCreateSurface*>( msg.get() )->getResult(); 2468} 2469status_t Client::destroySurface(SurfaceID sid) { 2470 return mFlinger->removeSurface(this, sid); 2471} 2472status_t Client::setState(int32_t count, const layer_state_t* states) { 2473 return mFlinger->setClientState(this, count, states); 2474} 2475 2476// --------------------------------------------------------------------------- 2477 2478GraphicBufferAlloc::GraphicBufferAlloc() {} 2479 2480GraphicBufferAlloc::~GraphicBufferAlloc() {} 2481 2482sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, 2483 PixelFormat format, uint32_t usage) { 2484 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 2485 status_t err = graphicBuffer->initCheck(); 2486 if (err != 0 || graphicBuffer->handle == 0) { 2487 GraphicBuffer::dumpAllocationsToSystemLog(); 2488 LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " 2489 "failed (%s), handle=%p", 2490 w, h, strerror(-err), graphicBuffer->handle); 2491 return 0; 2492 } 2493 return graphicBuffer; 2494} 2495 2496// --------------------------------------------------------------------------- 2497 2498GraphicPlane::GraphicPlane() 2499 : mHw(0) 2500{ 2501} 2502 2503GraphicPlane::~GraphicPlane() { 2504 delete mHw; 2505} 2506 2507bool GraphicPlane::initialized() const { 2508 return mHw ? true : false; 2509} 2510 2511int GraphicPlane::getWidth() const { 2512 return mWidth; 2513} 2514 2515int GraphicPlane::getHeight() const { 2516 return mHeight; 2517} 2518 2519void GraphicPlane::setDisplayHardware(DisplayHardware *hw) 2520{ 2521 mHw = hw; 2522 2523 // initialize the display orientation transform. 2524 // it's a constant that should come from the display driver. 2525 int displayOrientation = ISurfaceComposer::eOrientationDefault; 2526 char property[PROPERTY_VALUE_MAX]; 2527 if (property_get("ro.sf.hwrotation", property, NULL) > 0) { 2528 //displayOrientation 2529 switch (atoi(property)) { 2530 case 90: 2531 displayOrientation = ISurfaceComposer::eOrientation90; 2532 break; 2533 case 270: 2534 displayOrientation = ISurfaceComposer::eOrientation270; 2535 break; 2536 } 2537 } 2538 2539 const float w = hw->getWidth(); 2540 const float h = hw->getHeight(); 2541 GraphicPlane::orientationToTransfrom(displayOrientation, w, h, 2542 &mDisplayTransform); 2543 if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) { 2544 mDisplayWidth = h; 2545 mDisplayHeight = w; 2546 } else { 2547 mDisplayWidth = w; 2548 mDisplayHeight = h; 2549 } 2550 2551 setOrientation(ISurfaceComposer::eOrientationDefault); 2552} 2553 2554status_t GraphicPlane::orientationToTransfrom( 2555 int orientation, int w, int h, Transform* tr) 2556{ 2557 uint32_t flags = 0; 2558 switch (orientation) { 2559 case ISurfaceComposer::eOrientationDefault: 2560 flags = Transform::ROT_0; 2561 break; 2562 case ISurfaceComposer::eOrientation90: 2563 flags = Transform::ROT_90; 2564 break; 2565 case ISurfaceComposer::eOrientation180: 2566 flags = Transform::ROT_180; 2567 break; 2568 case ISurfaceComposer::eOrientation270: 2569 flags = Transform::ROT_270; 2570 break; 2571 default: 2572 return BAD_VALUE; 2573 } 2574 tr->set(flags, w, h); 2575 return NO_ERROR; 2576} 2577 2578status_t GraphicPlane::setOrientation(int orientation) 2579{ 2580 // If the rotation can be handled in hardware, this is where 2581 // the magic should happen. 2582 2583 const DisplayHardware& hw(displayHardware()); 2584 const float w = mDisplayWidth; 2585 const float h = mDisplayHeight; 2586 mWidth = int(w); 2587 mHeight = int(h); 2588 2589 Transform orientationTransform; 2590 GraphicPlane::orientationToTransfrom(orientation, w, h, 2591 &orientationTransform); 2592 if (orientation & ISurfaceComposer::eOrientationSwapMask) { 2593 mWidth = int(h); 2594 mHeight = int(w); 2595 } 2596 2597 mOrientation = orientation; 2598 mGlobalTransform = mDisplayTransform * orientationTransform; 2599 return NO_ERROR; 2600} 2601 2602const DisplayHardware& GraphicPlane::displayHardware() const { 2603 return *mHw; 2604} 2605 2606DisplayHardware& GraphicPlane::editDisplayHardware() { 2607 return *mHw; 2608} 2609 2610const Transform& GraphicPlane::transform() const { 2611 return mGlobalTransform; 2612} 2613 2614EGLDisplay GraphicPlane::getEGLDisplay() const { 2615 return mHw->getEGLDisplay(); 2616} 2617 2618// --------------------------------------------------------------------------- 2619 2620}; // namespace android 2621