Layer.cpp revision 16f0453fee84c6aad59fe0d1c7d36f061d46cffc
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 <stdint.h> 19#include <sys/types.h> 20 21#include <cutils/properties.h> 22#include <cutils/native_handle.h> 23 24#include <utils/Errors.h> 25#include <utils/Log.h> 26#include <utils/StopWatch.h> 27 28#include <ui/GraphicBuffer.h> 29#include <ui/PixelFormat.h> 30 31#include <surfaceflinger/Surface.h> 32 33#include "clz.h" 34#include "GLExtensions.h" 35#include "Layer.h" 36#include "SurfaceFlinger.h" 37#include "DisplayHardware/DisplayHardware.h" 38#include "DisplayHardware/HWComposer.h" 39 40 41#define DEBUG_RESIZE 0 42 43 44namespace android { 45 46template <typename T> inline T min(T a, T b) { 47 return a<b ? a : b; 48} 49 50// --------------------------------------------------------------------------- 51 52Layer::Layer(SurfaceFlinger* flinger, 53 DisplayID display, const sp<Client>& client) 54 : LayerBaseClient(flinger, display, client), 55 mGLExtensions(GLExtensions::getInstance()), 56 mNeedsBlending(true), 57 mNeedsDithering(false), 58 mSecure(false), 59 mProtectedByApp(false), 60 mProtectedByDRM(false), 61 mTextureManager(), 62 mBufferManager(mTextureManager), 63 mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false) 64{ 65} 66 67Layer::~Layer() 68{ 69 // FIXME: must be called from the main UI thread 70 EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 71 mBufferManager.destroy(dpy); 72 73 // we can use getUserClientUnsafe here because we know we're 74 // single-threaded at that point. 75 sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe()); 76 if (ourClient != 0) { 77 ourClient->detachLayer(this); 78 } 79} 80 81status_t Layer::setToken(const sp<UserClient>& userClient, 82 SharedClient* sharedClient, int32_t token) 83{ 84 sp<SharedBufferServer> lcblk = new SharedBufferServer( 85 sharedClient, token, mBufferManager.getDefaultBufferCount(), 86 getIdentity()); 87 88 89 sp<UserClient> ourClient(mUserClientRef.getClient()); 90 91 /* 92 * Here it is guaranteed that userClient != ourClient 93 * (see UserClient::getTokenForSurface()). 94 * 95 * We release the token used by this surface in ourClient below. 96 * This should be safe to do so now, since this layer won't be attached 97 * to this client, it should be okay to reuse that id. 98 * 99 * If this causes problems, an other solution would be to keep a list 100 * of all the {UserClient, token} ever used and release them when the 101 * Layer is destroyed. 102 * 103 */ 104 105 if (ourClient != 0) { 106 ourClient->detachLayer(this); 107 } 108 109 status_t err = mUserClientRef.setToken(userClient, lcblk, token); 110 LOGE_IF(err != NO_ERROR, 111 "ClientRef::setToken(%p, %p, %u) failed", 112 userClient.get(), lcblk.get(), token); 113 114 if (err == NO_ERROR) { 115 // we need to free the buffers associated with this surface 116 } 117 118 return err; 119} 120 121int32_t Layer::getToken() const 122{ 123 return mUserClientRef.getToken(); 124} 125 126sp<UserClient> Layer::getClient() const 127{ 128 return mUserClientRef.getClient(); 129} 130 131// called with SurfaceFlinger::mStateLock as soon as the layer is entered 132// in the purgatory list 133void Layer::onRemoved() 134{ 135 ClientRef::Access sharedClient(mUserClientRef); 136 SharedBufferServer* lcblk(sharedClient.get()); 137 if (lcblk) { 138 // wake up the condition 139 lcblk->setStatus(NO_INIT); 140 } 141} 142 143sp<LayerBaseClient::Surface> Layer::createSurface() const 144{ 145 return mSurface; 146} 147 148status_t Layer::ditch() 149{ 150 // NOTE: Called from the main UI thread 151 152 // the layer is not on screen anymore. free as much resources as possible 153 mFreezeLock.clear(); 154 155 EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 156 mBufferManager.destroy(dpy); 157 mSurface.clear(); 158 159 Mutex::Autolock _l(mLock); 160 mWidth = mHeight = 0; 161 return NO_ERROR; 162} 163 164status_t Layer::setBuffers( uint32_t w, uint32_t h, 165 PixelFormat format, uint32_t flags) 166{ 167 // this surfaces pixel format 168 PixelFormatInfo info; 169 status_t err = getPixelFormatInfo(format, &info); 170 if (err) return err; 171 172 // the display's pixel format 173 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 174 uint32_t const maxSurfaceDims = min( 175 hw.getMaxTextureSize(), hw.getMaxViewportDims()); 176 177 // never allow a surface larger than what our underlying GL implementation 178 // can handle. 179 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 180 return BAD_VALUE; 181 } 182 183 PixelFormatInfo displayInfo; 184 getPixelFormatInfo(hw.getFormat(), &displayInfo); 185 const uint32_t hwFlags = hw.getFlags(); 186 187 mFormat = format; 188 mWidth = w; 189 mHeight = h; 190 191 mReqFormat = format; 192 mReqWidth = w; 193 mReqHeight = h; 194 195 mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 196 mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; 197 mProtectedByDRM = (flags & ISurfaceComposer::eProtectedByDRM) ? true : false; 198 mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 && 199 (flags & ISurfaceComposer::eOpaque) == 0; 200 201 // we use the red index 202 int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 203 int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 204 mNeedsDithering = layerRedsize > displayRedSize; 205 206 mSurface = new SurfaceLayer(mFlinger, this); 207 return NO_ERROR; 208} 209 210void Layer::setGeometry(hwc_layer_t* hwcl) 211{ 212 hwcl->compositionType = HWC_FRAMEBUFFER; 213 hwcl->hints = 0; 214 hwcl->flags = 0; 215 hwcl->transform = 0; 216 hwcl->blending = HWC_BLENDING_NONE; 217 218 // we can't do alpha-fade with the hwc HAL 219 const State& s(drawingState()); 220 if (s.alpha < 0xFF) { 221 hwcl->flags = HWC_SKIP_LAYER; 222 return; 223 } 224 225 // we can only handle simple transformation 226 if (mOrientation & Transform::ROT_INVALID) { 227 hwcl->flags = HWC_SKIP_LAYER; 228 return; 229 } 230 231 Transform tr(Transform(mOrientation) * Transform(mBufferTransform)); 232 hwcl->transform = tr.getOrientation(); 233 234 if (needsBlending()) { 235 hwcl->blending = mPremultipliedAlpha ? 236 HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE; 237 } 238 239 hwcl->displayFrame.left = mTransformedBounds.left; 240 hwcl->displayFrame.top = mTransformedBounds.top; 241 hwcl->displayFrame.right = mTransformedBounds.right; 242 hwcl->displayFrame.bottom = mTransformedBounds.bottom; 243 244 hwcl->visibleRegionScreen.rects = 245 reinterpret_cast<hwc_rect_t const *>( 246 visibleRegionScreen.getArray( 247 &hwcl->visibleRegionScreen.numRects)); 248} 249 250void Layer::setPerFrameData(hwc_layer_t* hwcl) { 251 sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 252 if (buffer == NULL) { 253 // this can happen if the client never drew into this layer yet, 254 // or if we ran out of memory. In that case, don't let 255 // HWC handle it. 256 hwcl->flags |= HWC_SKIP_LAYER; 257 hwcl->handle = NULL; 258 return; 259 } 260 hwcl->handle = buffer->handle; 261 262 if (!mBufferCrop.isEmpty()) { 263 hwcl->sourceCrop.left = mBufferCrop.left; 264 hwcl->sourceCrop.top = mBufferCrop.top; 265 hwcl->sourceCrop.right = mBufferCrop.right; 266 hwcl->sourceCrop.bottom = mBufferCrop.bottom; 267 } else { 268 hwcl->sourceCrop.left = 0; 269 hwcl->sourceCrop.top = 0; 270 hwcl->sourceCrop.right = buffer->width; 271 hwcl->sourceCrop.bottom = buffer->height; 272 } 273} 274 275void Layer::reloadTexture(const Region& dirty) 276{ 277 sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 278 if (buffer == NULL) { 279 // this situation can happen if we ran out of memory for instance. 280 // not much we can do. continue to use whatever texture was bound 281 // to this context. 282 return; 283 } 284 285 if (mGLExtensions.haveDirectTexture()) { 286 EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 287 if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) { 288 // not sure what we can do here... 289 goto slowpath; 290 } 291 } else { 292slowpath: 293 GGLSurface t; 294 if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) { 295 status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN); 296 LOGE_IF(res, "error %d (%s) locking buffer %p", 297 res, strerror(res), buffer.get()); 298 if (res == NO_ERROR) { 299 mBufferManager.loadTexture(dirty, t); 300 buffer->unlock(); 301 } 302 } else { 303 // we can't do anything 304 } 305 } 306} 307 308void Layer::drawForSreenShot() const 309{ 310 const bool currentFiltering = mNeedsFiltering; 311 const_cast<Layer*>(this)->mNeedsFiltering = true; 312 LayerBase::drawForSreenShot(); 313 const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering; 314} 315 316void Layer::onDraw(const Region& clip) const 317{ 318 Texture tex(mBufferManager.getActiveTexture()); 319 if (tex.name == -1LU) { 320 // the texture has not been created yet, this Layer has 321 // in fact never been drawn into. This happens frequently with 322 // SurfaceView because the WindowManager can't know when the client 323 // has drawn the first time. 324 325 // If there is nothing under us, we paint the screen in black, otherwise 326 // we just skip this update. 327 328 // figure out if there is something below us 329 Region under; 330 const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); 331 const size_t count = drawingLayers.size(); 332 for (size_t i=0 ; i<count ; ++i) { 333 const sp<LayerBase>& layer(drawingLayers[i]); 334 if (layer.get() == static_cast<LayerBase const*>(this)) 335 break; 336 under.orSelf(layer->visibleRegionScreen); 337 } 338 // if not everything below us is covered, we plug the holes! 339 Region holes(clip.subtract(under)); 340 if (!holes.isEmpty()) { 341 clearWithOpenGL(holes, 0, 0, 0, 1); 342 } 343 return; 344 } 345 drawWithOpenGL(clip, tex); 346} 347 348bool Layer::needsFiltering() const 349{ 350 if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { 351 // if our buffer is not the same size than ourselves, 352 // we need filtering. 353 Mutex::Autolock _l(mLock); 354 if (mNeedsScaling) 355 return true; 356 } 357 return LayerBase::needsFiltering(); 358} 359 360 361status_t Layer::setBufferCount(int bufferCount) 362{ 363 ClientRef::Access sharedClient(mUserClientRef); 364 SharedBufferServer* lcblk(sharedClient.get()); 365 if (!lcblk) { 366 // oops, the client is already gone 367 return DEAD_OBJECT; 368 } 369 370 // NOTE: lcblk->resize() is protected by an internal lock 371 status_t err = lcblk->resize(bufferCount); 372 if (err == NO_ERROR) { 373 EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay()); 374 mBufferManager.resize(bufferCount, mFlinger, dpy); 375 } 376 377 return err; 378} 379 380sp<GraphicBuffer> Layer::requestBuffer(int index, 381 uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat, 382 uint32_t usage) 383{ 384 sp<GraphicBuffer> buffer; 385 386 if (int32_t(reqWidth | reqHeight | reqFormat) < 0) 387 return buffer; 388 389 if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight)) 390 return buffer; 391 392 // this ensures our client doesn't go away while we're accessing 393 // the shared area. 394 ClientRef::Access sharedClient(mUserClientRef); 395 SharedBufferServer* lcblk(sharedClient.get()); 396 if (!lcblk) { 397 // oops, the client is already gone 398 return buffer; 399 } 400 401 /* 402 * This is called from the client's Surface::dequeue(). This can happen 403 * at any time, especially while we're in the middle of using the 404 * buffer 'index' as our front buffer. 405 */ 406 407 status_t err = NO_ERROR; 408 uint32_t w, h, f; 409 { // scope for the lock 410 Mutex::Autolock _l(mLock); 411 412 // zero means default 413 const bool fixedSize = reqWidth && reqHeight; 414 if (!reqFormat) reqFormat = mFormat; 415 if (!reqWidth) reqWidth = mWidth; 416 if (!reqHeight) reqHeight = mHeight; 417 418 w = reqWidth; 419 h = reqHeight; 420 f = reqFormat; 421 422 if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) || 423 (reqFormat != mReqFormat)) { 424 mReqWidth = reqWidth; 425 mReqHeight = reqHeight; 426 mReqFormat = reqFormat; 427 mFixedSize = fixedSize; 428 mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 429 430 lcblk->reallocateAllExcept(index); 431 } 432 } 433 434 // here we have to reallocate a new buffer because the buffer could be 435 // used as the front buffer, or by a client in our process 436 // (eg: status bar), and we can't release the handle under its feet. 437 const uint32_t effectiveUsage = getEffectiveUsage(usage); 438 buffer = new GraphicBuffer(w, h, f, effectiveUsage); 439 err = buffer->initCheck(); 440 441 if (err || buffer->handle == 0) { 442 GraphicBuffer::dumpAllocationsToSystemLog(); 443 LOGE_IF(err || buffer->handle == 0, 444 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 445 this, index, w, h, strerror(-err)); 446 } else { 447 LOGD_IF(DEBUG_RESIZE, 448 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 449 this, index, w, h, buffer->handle); 450 } 451 452 if (err == NO_ERROR && buffer->handle != 0) { 453 Mutex::Autolock _l(mLock); 454 mBufferManager.attachBuffer(index, buffer); 455 } 456 return buffer; 457} 458 459uint32_t Layer::getEffectiveUsage(uint32_t usage) const 460{ 461 /* 462 * buffers used for software rendering, but h/w composition 463 * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 464 * 465 * buffers used for h/w rendering and h/w composition 466 * are allocated with HW_RENDER | HW_TEXTURE 467 * 468 * buffers used with h/w rendering and either NPOT or no egl_image_ext 469 * are allocated with SW_READ_RARELY | HW_RENDER 470 * 471 */ 472 473 if (mSecure) { 474 // secure buffer, don't store it into the GPU 475 usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 476 GraphicBuffer::USAGE_SW_WRITE_OFTEN; 477 } else { 478 // it's allowed to modify the usage flags here, but generally 479 // the requested flags should be honored. 480 // request EGLImage for all buffers 481 usage |= GraphicBuffer::USAGE_HW_TEXTURE; 482 } 483 if (mProtectedByApp || mProtectedByDRM) { 484 // need a hardware-protected path to external video sink 485 usage |= GraphicBuffer::USAGE_PROTECTED; 486 } 487 return usage; 488} 489 490uint32_t Layer::doTransaction(uint32_t flags) 491{ 492 const Layer::State& front(drawingState()); 493 const Layer::State& temp(currentState()); 494 495 const bool sizeChanged = (front.requested_w != temp.requested_w) || 496 (front.requested_h != temp.requested_h); 497 498 if (sizeChanged) { 499 // the size changed, we need to ask our client to request a new buffer 500 LOGD_IF(DEBUG_RESIZE, 501 "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 502 this, 503 int(temp.requested_w), int(temp.requested_h), 504 int(front.requested_w), int(front.requested_h)); 505 506 if (!isFixedSize()) { 507 // we're being resized and there is a freeze display request, 508 // acquire a freeze lock, so that the screen stays put 509 // until we've redrawn at the new size; this is to avoid 510 // glitches upon orientation changes. 511 if (mFlinger->hasFreezeRequest()) { 512 // if the surface is hidden, don't try to acquire the 513 // freeze lock, since hidden surfaces may never redraw 514 if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 515 mFreezeLock = mFlinger->getFreezeLock(); 516 } 517 } 518 519 // this will make sure LayerBase::doTransaction doesn't update 520 // the drawing state's size 521 Layer::State& editDraw(mDrawingState); 522 editDraw.requested_w = temp.requested_w; 523 editDraw.requested_h = temp.requested_h; 524 525 // record the new size, form this point on, when the client request 526 // a buffer, it'll get the new size. 527 setBufferSize(temp.requested_w, temp.requested_h); 528 529 ClientRef::Access sharedClient(mUserClientRef); 530 SharedBufferServer* lcblk(sharedClient.get()); 531 if (lcblk) { 532 // all buffers need reallocation 533 lcblk->reallocateAll(); 534 } 535 } else { 536 // record the new size 537 setBufferSize(temp.requested_w, temp.requested_h); 538 } 539 } 540 541 if (temp.sequence != front.sequence) { 542 if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 543 // this surface is now hidden, so it shouldn't hold a freeze lock 544 // (it may never redraw, which is fine if it is hidden) 545 mFreezeLock.clear(); 546 } 547 } 548 549 return LayerBase::doTransaction(flags); 550} 551 552void Layer::setBufferSize(uint32_t w, uint32_t h) { 553 Mutex::Autolock _l(mLock); 554 mWidth = w; 555 mHeight = h; 556 mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight; 557} 558 559bool Layer::isFixedSize() const { 560 Mutex::Autolock _l(mLock); 561 return mFixedSize; 562} 563 564// ---------------------------------------------------------------------------- 565// pageflip handling... 566// ---------------------------------------------------------------------------- 567 568void Layer::lockPageFlip(bool& recomputeVisibleRegions) 569{ 570 ClientRef::Access sharedClient(mUserClientRef); 571 SharedBufferServer* lcblk(sharedClient.get()); 572 if (!lcblk) { 573 // client died 574 recomputeVisibleRegions = true; 575 return; 576 } 577 578 ssize_t buf = lcblk->retireAndLock(); 579 if (buf == NOT_ENOUGH_DATA) { 580 // NOTE: This is not an error, it simply means there is nothing to 581 // retire. The buffer is locked because we will use it 582 // for composition later in the loop 583 return; 584 } 585 586 if (buf < NO_ERROR) { 587 LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 588 mPostedDirtyRegion.clear(); 589 return; 590 } 591 592 // we retired a buffer, which becomes the new front buffer 593 594 const bool noActiveBuffer = !mBufferManager.hasActiveBuffer(); 595 if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 596 LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 597 mPostedDirtyRegion.clear(); 598 return; 599 } 600 601 if (noActiveBuffer) { 602 // we didn't have an active buffer, we need to recompute 603 // our visible region 604 recomputeVisibleRegions = true; 605 } 606 607 sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 608 if (newFrontBuffer != NULL) { 609 // get the dirty region 610 // compute the posted region 611 const Region dirty(lcblk->getDirtyRegion(buf)); 612 mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 613 614 // update the layer size and release freeze-lock 615 const Layer::State& front(drawingState()); 616 if (newFrontBuffer->getWidth() == front.requested_w && 617 newFrontBuffer->getHeight() == front.requested_h) 618 { 619 if ((front.w != front.requested_w) || 620 (front.h != front.requested_h)) 621 { 622 // Here we pretend the transaction happened by updating the 623 // current and drawing states. Drawing state is only accessed 624 // in this thread, no need to have it locked 625 Layer::State& editDraw(mDrawingState); 626 editDraw.w = editDraw.requested_w; 627 editDraw.h = editDraw.requested_h; 628 629 // We also need to update the current state so that we don't 630 // end-up doing too much work during the next transaction. 631 // NOTE: We actually don't need hold the transaction lock here 632 // because State::w and State::h are only accessed from 633 // this thread 634 Layer::State& editTemp(currentState()); 635 editTemp.w = editDraw.w; 636 editTemp.h = editDraw.h; 637 638 // recompute visible region 639 recomputeVisibleRegions = true; 640 } 641 642 // we now have the correct size, unfreeze the screen 643 mFreezeLock.clear(); 644 } 645 646 // get the crop region 647 setBufferCrop( lcblk->getCrop(buf) ); 648 649 // get the transformation 650 setBufferTransform( lcblk->getTransform(buf) ); 651 652 } else { 653 // this should not happen unless we ran out of memory while 654 // allocating the buffer. we're hoping that things will get back 655 // to normal the next time the app tries to draw into this buffer. 656 // meanwhile, pretend the screen didn't update. 657 mPostedDirtyRegion.clear(); 658 } 659 660 if (lcblk->getQueuedCount()) { 661 // signal an event if we have more buffers waiting 662 mFlinger->signalEvent(); 663 } 664 665 /* a buffer was posted, so we need to call reloadTexture(), which 666 * will update our internal data structures (eg: EGLImageKHR or 667 * texture names). we need to do this even if mPostedDirtyRegion is 668 * empty -- it's orthogonal to the fact that a new buffer was posted, 669 * for instance, a degenerate case could be that the user did an empty 670 * update but repainted the buffer with appropriate content (after a 671 * resize for instance). 672 */ 673 reloadTexture( mPostedDirtyRegion ); 674} 675 676void Layer::unlockPageFlip( 677 const Transform& planeTransform, Region& outDirtyRegion) 678{ 679 Region dirtyRegion(mPostedDirtyRegion); 680 if (!dirtyRegion.isEmpty()) { 681 mPostedDirtyRegion.clear(); 682 // The dirty region is given in the layer's coordinate space 683 // transform the dirty region by the surface's transformation 684 // and the global transformation. 685 const Layer::State& s(drawingState()); 686 const Transform tr(planeTransform * s.transform); 687 dirtyRegion = tr.transform(dirtyRegion); 688 689 // At this point, the dirty region is in screen space. 690 // Make sure it's constrained by the visible region (which 691 // is in screen space as well). 692 dirtyRegion.andSelf(visibleRegionScreen); 693 outDirtyRegion.orSelf(dirtyRegion); 694 } 695 if (visibleRegionScreen.isEmpty()) { 696 // an invisible layer should not hold a freeze-lock 697 // (because it may never be updated and therefore never release it) 698 mFreezeLock.clear(); 699 } 700} 701 702void Layer::dump(String8& result, char* buffer, size_t SIZE) const 703{ 704 LayerBaseClient::dump(result, buffer, SIZE); 705 706 ClientRef::Access sharedClient(mUserClientRef); 707 SharedBufferServer* lcblk(sharedClient.get()); 708 uint32_t totalTime = 0; 709 if (lcblk) { 710 SharedBufferStack::Statistics stats = lcblk->getStats(); 711 totalTime= stats.totalTime; 712 result.append( lcblk->dump(" ") ); 713 } 714 715 sp<const GraphicBuffer> buf0(getBuffer(0)); 716 sp<const GraphicBuffer> buf1(getBuffer(1)); 717 uint32_t w0=0, h0=0, s0=0; 718 uint32_t w1=0, h1=0, s1=0; 719 if (buf0 != 0) { 720 w0 = buf0->getWidth(); 721 h0 = buf0->getHeight(); 722 s0 = buf0->getStride(); 723 } 724 if (buf1 != 0) { 725 w1 = buf1->getWidth(); 726 h1 = buf1->getHeight(); 727 s1 = buf1->getStride(); 728 } 729 snprintf(buffer, SIZE, 730 " " 731 "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 732 " freezeLock=%p, dq-q-time=%u us\n", 733 mFormat, w0, h0, s0, w1, h1, s1, 734 getFreezeLock().get(), totalTime); 735 736 result.append(buffer); 737} 738 739// --------------------------------------------------------------------------- 740 741Layer::ClientRef::ClientRef() 742 : mControlBlock(0), mToken(-1) { 743} 744 745Layer::ClientRef::~ClientRef() { 746} 747 748int32_t Layer::ClientRef::getToken() const { 749 Mutex::Autolock _l(mLock); 750 return mToken; 751} 752 753sp<UserClient> Layer::ClientRef::getClient() const { 754 Mutex::Autolock _l(mLock); 755 return mUserClient.promote(); 756} 757 758status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 759 const sp<SharedBufferServer>& sharedClient, int32_t token) { 760 Mutex::Autolock _l(mLock); 761 762 { // scope for strong mUserClient reference 763 sp<UserClient> userClient(mUserClient.promote()); 764 if (mUserClient != 0 && mControlBlock != 0) { 765 mControlBlock->setStatus(NO_INIT); 766 } 767 } 768 769 mUserClient = uc; 770 mToken = token; 771 mControlBlock = sharedClient; 772 return NO_ERROR; 773} 774 775sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 776 return mUserClient.promote(); 777} 778 779// this class gives us access to SharedBufferServer safely 780// it makes sure the UserClient (and its associated shared memory) 781// won't go away while we're accessing it. 782Layer::ClientRef::Access::Access(const ClientRef& ref) 783 : mControlBlock(0) 784{ 785 Mutex::Autolock _l(ref.mLock); 786 mUserClientStrongRef = ref.mUserClient.promote(); 787 if (mUserClientStrongRef != 0) 788 mControlBlock = ref.mControlBlock; 789} 790 791Layer::ClientRef::Access::~Access() 792{ 793} 794 795// --------------------------------------------------------------------------- 796 797Layer::BufferManager::BufferManager(TextureManager& tm) 798 : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 799 mActiveBufferIndex(-1), mFailover(false) 800{ 801} 802 803Layer::BufferManager::~BufferManager() 804{ 805} 806 807status_t Layer::BufferManager::resize(size_t size, 808 const sp<SurfaceFlinger>& flinger, EGLDisplay dpy) 809{ 810 Mutex::Autolock _l(mLock); 811 812 if (size < mNumBuffers) { 813 // Move the active texture into slot 0 814 BufferData activeBufferData = mBufferData[mActiveBufferIndex]; 815 mBufferData[mActiveBufferIndex] = mBufferData[0]; 816 mBufferData[0] = activeBufferData; 817 mActiveBufferIndex = 0; 818 819 // Free the buffers that are no longer needed. 820 for (size_t i = size; i < mNumBuffers; i++) { 821 mBufferData[i].buffer = 0; 822 823 // Create a message to destroy the textures on SurfaceFlinger's GL 824 // thread. 825 class MessageDestroyTexture : public MessageBase { 826 Image mTexture; 827 EGLDisplay mDpy; 828 public: 829 MessageDestroyTexture(const Image& texture, EGLDisplay dpy) 830 : mTexture(texture), mDpy(dpy) { } 831 virtual bool handler() { 832 status_t err = Layer::BufferManager::destroyTexture( 833 &mTexture, mDpy); 834 LOGE_IF(err<0, "error destroying texture: %d (%s)", 835 mTexture.name, strerror(-err)); 836 return true; // XXX: err == 0; ???? 837 } 838 }; 839 840 MessageDestroyTexture *msg = new MessageDestroyTexture( 841 mBufferData[i].texture, dpy); 842 843 // Don't allow this texture to be cleaned up by 844 // BufferManager::destroy. 845 mBufferData[i].texture.name = -1U; 846 mBufferData[i].texture.image = EGL_NO_IMAGE_KHR; 847 848 // Post the message to the SurfaceFlinger object. 849 flinger->postMessageAsync(msg); 850 } 851 } 852 853 mNumBuffers = size; 854 return NO_ERROR; 855} 856 857// only for debugging 858sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 859 return mBufferData[index].buffer; 860} 861 862status_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 863 BufferData const * const buffers = mBufferData; 864 Mutex::Autolock _l(mLock); 865 mActiveBuffer = buffers[index].buffer; 866 mActiveBufferIndex = index; 867 return NO_ERROR; 868} 869 870size_t Layer::BufferManager::getActiveBufferIndex() const { 871 return mActiveBufferIndex; 872} 873 874Texture Layer::BufferManager::getActiveTexture() const { 875 Texture res; 876 if (mFailover || mActiveBufferIndex<0) { 877 res = mFailoverTexture; 878 } else { 879 static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture; 880 } 881 return res; 882} 883 884sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 885 return mActiveBuffer; 886} 887 888bool Layer::BufferManager::hasActiveBuffer() const { 889 return mActiveBufferIndex >= 0; 890} 891 892sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 893{ 894 BufferData* const buffers = mBufferData; 895 sp<GraphicBuffer> buffer; 896 Mutex::Autolock _l(mLock); 897 buffer = buffers[index].buffer; 898 buffers[index].buffer = 0; 899 return buffer; 900} 901 902status_t Layer::BufferManager::attachBuffer(size_t index, 903 const sp<GraphicBuffer>& buffer) 904{ 905 BufferData* const buffers = mBufferData; 906 Mutex::Autolock _l(mLock); 907 buffers[index].buffer = buffer; 908 buffers[index].texture.dirty = true; 909 return NO_ERROR; 910} 911 912status_t Layer::BufferManager::destroy(EGLDisplay dpy) 913{ 914 BufferData* const buffers = mBufferData; 915 size_t num; 916 { // scope for the lock 917 Mutex::Autolock _l(mLock); 918 num = mNumBuffers; 919 for (size_t i=0 ; i<num ; i++) { 920 buffers[i].buffer = 0; 921 } 922 } 923 for (size_t i=0 ; i<num ; i++) { 924 destroyTexture(&buffers[i].texture, dpy); 925 } 926 destroyTexture(&mFailoverTexture, dpy); 927 return NO_ERROR; 928} 929 930status_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 931 const sp<GraphicBuffer>& buffer) 932{ 933 status_t err = NO_INIT; 934 ssize_t index = mActiveBufferIndex; 935 if (index >= 0) { 936 if (!mFailover) { 937 Image& texture(mBufferData[index].texture); 938 err = mTextureManager.initEglImage(&texture, dpy, buffer); 939 // if EGLImage fails, we switch to regular texture mode, and we 940 // free all resources associated with using EGLImages. 941 if (err == NO_ERROR) { 942 mFailover = false; 943 destroyTexture(&mFailoverTexture, dpy); 944 } else { 945 mFailover = true; 946 const size_t num = mNumBuffers; 947 for (size_t i=0 ; i<num ; i++) { 948 destroyTexture(&mBufferData[i].texture, dpy); 949 } 950 } 951 } else { 952 // we failed once, don't try again 953 err = BAD_VALUE; 954 } 955 } 956 return err; 957} 958 959status_t Layer::BufferManager::loadTexture( 960 const Region& dirty, const GGLSurface& t) 961{ 962 return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 963} 964 965status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 966{ 967 if (tex->name != -1U) { 968 glDeleteTextures(1, &tex->name); 969 tex->name = -1U; 970 } 971 if (tex->image != EGL_NO_IMAGE_KHR) { 972 eglDestroyImageKHR(dpy, tex->image); 973 tex->image = EGL_NO_IMAGE_KHR; 974 } 975 return NO_ERROR; 976} 977 978// --------------------------------------------------------------------------- 979 980Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 981 const sp<Layer>& owner) 982 : Surface(flinger, owner->getIdentity(), owner) 983{ 984} 985 986Layer::SurfaceLayer::~SurfaceLayer() 987{ 988} 989 990sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 991 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 992{ 993 sp<GraphicBuffer> buffer; 994 sp<Layer> owner(getOwner()); 995 if (owner != 0) { 996 /* 997 * requestBuffer() cannot be called from the main thread 998 * as it could cause a dead-lock, since it may have to wait 999 * on conditions updated my the main thread. 1000 */ 1001 buffer = owner->requestBuffer(index, w, h, format, usage); 1002 } 1003 return buffer; 1004} 1005 1006status_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 1007{ 1008 status_t err = DEAD_OBJECT; 1009 sp<Layer> owner(getOwner()); 1010 if (owner != 0) { 1011 /* 1012 * setBufferCount() cannot be called from the main thread 1013 * as it could cause a dead-lock, since it may have to wait 1014 * on conditions updated my the main thread. 1015 */ 1016 err = owner->setBufferCount(bufferCount); 1017 } 1018 return err; 1019} 1020 1021// --------------------------------------------------------------------------- 1022 1023 1024}; // namespace android 1025