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