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