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