Layer.cpp revision 3cc2677efc2a4bc06297b9667ac529284f6abf9d
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 // Free our own reference to ISurface 154 mSurface.clear(); 155 156 Mutex::Autolock _l(mLock); 157 mWidth = mHeight = 0; 158 return NO_ERROR; 159} 160 161status_t Layer::setBuffers( uint32_t w, uint32_t h, 162 PixelFormat format, uint32_t flags) 163{ 164 // this surfaces pixel format 165 PixelFormatInfo info; 166 status_t err = getPixelFormatInfo(format, &info); 167 if (err) return err; 168 169 // the display's pixel format 170 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 171 uint32_t const maxSurfaceDims = min( 172 hw.getMaxTextureSize(), hw.getMaxViewportDims()); 173 174 // never allow a surface larger than what our underlying GL implementation 175 // can handle. 176 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 177 return BAD_VALUE; 178 } 179 180 PixelFormatInfo displayInfo; 181 getPixelFormatInfo(hw.getFormat(), &displayInfo); 182 const uint32_t hwFlags = hw.getFlags(); 183 184 mFormat = format; 185 mWidth = w; 186 mHeight = h; 187 188 mReqFormat = format; 189 mReqWidth = w; 190 mReqHeight = h; 191 192 mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 193 mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 && 194 (flags & ISurfaceComposer::eOpaque) == 0; 195 196 // we use the red index 197 int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 198 int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 199 mNeedsDithering = layerRedsize > displayRedSize; 200 201 mSurface = new SurfaceLayer(mFlinger, this); 202 return NO_ERROR; 203} 204 205void Layer::setGeometry(hwc_layer_t* hwcl) 206{ 207 hwcl->compositionType = HWC_FRAMEBUFFER; 208 hwcl->hints = 0; 209 hwcl->flags = 0; 210 hwcl->transform = 0; 211 hwcl->blending = HWC_BLENDING_NONE; 212 213 // we can't do alpha-fade with the hwc HAL 214 const State& s(drawingState()); 215 if (s.alpha < 0xFF) { 216 hwcl->flags = HWC_SKIP_LAYER; 217 return; 218 } 219 220 // we can only handle simple transformation 221 if (mOrientation & Transform::ROT_INVALID) { 222 hwcl->flags = HWC_SKIP_LAYER; 223 return; 224 } 225 226 Transform tr(Transform(mOrientation) * Transform(mBufferTransform)); 227 hwcl->transform = tr.getOrientation(); 228 229 if (needsBlending()) { 230 hwcl->blending = mPremultipliedAlpha ? 231 HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE; 232 } 233 234 hwcl->displayFrame.left = mTransformedBounds.left; 235 hwcl->displayFrame.top = mTransformedBounds.top; 236 hwcl->displayFrame.right = mTransformedBounds.right; 237 hwcl->displayFrame.bottom = mTransformedBounds.bottom; 238 239 hwcl->visibleRegionScreen.rects = 240 reinterpret_cast<hwc_rect_t const *>( 241 visibleRegionScreen.getArray( 242 &hwcl->visibleRegionScreen.numRects)); 243} 244 245void Layer::setPerFrameData(hwc_layer_t* hwcl) { 246 sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer()); 247 if (buffer == NULL) { 248 // this can happen if the client never drew into this layer yet, 249 // or if we ran out of memory. In that case, don't let 250 // HWC handle it. 251 hwcl->flags |= HWC_SKIP_LAYER; 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 585 const bool noActiveBuffer = !mBufferManager.hasActiveBuffer(); 586 if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 587 LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 588 mPostedDirtyRegion.clear(); 589 return; 590 } 591 592 if (noActiveBuffer) { 593 // we didn't have an active buffer, we need to recompute 594 // our visible region 595 recomputeVisibleRegions = true; 596 } 597 598 sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 599 if (newFrontBuffer != NULL) { 600 // get the dirty region 601 // compute the posted region 602 const Region dirty(lcblk->getDirtyRegion(buf)); 603 mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 604 605 // update the layer size and release freeze-lock 606 const Layer::State& front(drawingState()); 607 if (newFrontBuffer->getWidth() == front.requested_w && 608 newFrontBuffer->getHeight() == front.requested_h) 609 { 610 if ((front.w != front.requested_w) || 611 (front.h != front.requested_h)) 612 { 613 // Here we pretend the transaction happened by updating the 614 // current and drawing states. Drawing state is only accessed 615 // in this thread, no need to have it locked 616 Layer::State& editDraw(mDrawingState); 617 editDraw.w = editDraw.requested_w; 618 editDraw.h = editDraw.requested_h; 619 620 // We also need to update the current state so that we don't 621 // end-up doing too much work during the next transaction. 622 // NOTE: We actually don't need hold the transaction lock here 623 // because State::w and State::h are only accessed from 624 // this thread 625 Layer::State& editTemp(currentState()); 626 editTemp.w = editDraw.w; 627 editTemp.h = editDraw.h; 628 629 // recompute visible region 630 recomputeVisibleRegions = true; 631 } 632 633 // we now have the correct size, unfreeze the screen 634 mFreezeLock.clear(); 635 } 636 637 // get the crop region 638 setBufferCrop( lcblk->getCrop(buf) ); 639 640 // get the transformation 641 setBufferTransform( lcblk->getTransform(buf) ); 642 643 } else { 644 // this should not happen unless we ran out of memory while 645 // allocating the buffer. we're hoping that things will get back 646 // to normal the next time the app tries to draw into this buffer. 647 // meanwhile, pretend the screen didn't update. 648 mPostedDirtyRegion.clear(); 649 } 650 651 if (lcblk->getQueuedCount()) { 652 // signal an event if we have more buffers waiting 653 mFlinger->signalEvent(); 654 } 655 656 /* a buffer was posted, so we need to call reloadTexture(), which 657 * will update our internal data structures (eg: EGLImageKHR or 658 * texture names). we need to do this even if mPostedDirtyRegion is 659 * empty -- it's orthogonal to the fact that a new buffer was posted, 660 * for instance, a degenerate case could be that the user did an empty 661 * update but repainted the buffer with appropriate content (after a 662 * resize for instance). 663 */ 664 reloadTexture( mPostedDirtyRegion ); 665} 666 667void Layer::unlockPageFlip( 668 const Transform& planeTransform, Region& outDirtyRegion) 669{ 670 Region dirtyRegion(mPostedDirtyRegion); 671 if (!dirtyRegion.isEmpty()) { 672 mPostedDirtyRegion.clear(); 673 // The dirty region is given in the layer's coordinate space 674 // transform the dirty region by the surface's transformation 675 // and the global transformation. 676 const Layer::State& s(drawingState()); 677 const Transform tr(planeTransform * s.transform); 678 dirtyRegion = tr.transform(dirtyRegion); 679 680 // At this point, the dirty region is in screen space. 681 // Make sure it's constrained by the visible region (which 682 // is in screen space as well). 683 dirtyRegion.andSelf(visibleRegionScreen); 684 outDirtyRegion.orSelf(dirtyRegion); 685 } 686 if (visibleRegionScreen.isEmpty()) { 687 // an invisible layer should not hold a freeze-lock 688 // (because it may never be updated and therefore never release it) 689 mFreezeLock.clear(); 690 } 691} 692 693void Layer::dump(String8& result, char* buffer, size_t SIZE) const 694{ 695 LayerBaseClient::dump(result, buffer, SIZE); 696 697 ClientRef::Access sharedClient(mUserClientRef); 698 SharedBufferServer* lcblk(sharedClient.get()); 699 uint32_t totalTime = 0; 700 if (lcblk) { 701 SharedBufferStack::Statistics stats = lcblk->getStats(); 702 totalTime= stats.totalTime; 703 result.append( lcblk->dump(" ") ); 704 } 705 706 sp<const GraphicBuffer> buf0(getBuffer(0)); 707 sp<const GraphicBuffer> buf1(getBuffer(1)); 708 uint32_t w0=0, h0=0, s0=0; 709 uint32_t w1=0, h1=0, s1=0; 710 if (buf0 != 0) { 711 w0 = buf0->getWidth(); 712 h0 = buf0->getHeight(); 713 s0 = buf0->getStride(); 714 } 715 if (buf1 != 0) { 716 w1 = buf1->getWidth(); 717 h1 = buf1->getHeight(); 718 s1 = buf1->getStride(); 719 } 720 snprintf(buffer, SIZE, 721 " " 722 "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 723 " freezeLock=%p, dq-q-time=%u us\n", 724 mFormat, w0, h0, s0, w1, h1, s1, 725 getFreezeLock().get(), totalTime); 726 727 result.append(buffer); 728} 729 730// --------------------------------------------------------------------------- 731 732Layer::ClientRef::ClientRef() 733 : mControlBlock(0), mToken(-1) { 734} 735 736Layer::ClientRef::~ClientRef() { 737} 738 739int32_t Layer::ClientRef::getToken() const { 740 Mutex::Autolock _l(mLock); 741 return mToken; 742} 743 744sp<UserClient> Layer::ClientRef::getClient() const { 745 Mutex::Autolock _l(mLock); 746 return mUserClient.promote(); 747} 748 749status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 750 const sp<SharedBufferServer>& sharedClient, int32_t token) { 751 Mutex::Autolock _l(mLock); 752 753 { // scope for strong mUserClient reference 754 sp<UserClient> userClient(mUserClient.promote()); 755 if (mUserClient != 0 && mControlBlock != 0) { 756 mControlBlock->setStatus(NO_INIT); 757 } 758 } 759 760 mUserClient = uc; 761 mToken = token; 762 mControlBlock = sharedClient; 763 return NO_ERROR; 764} 765 766sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 767 return mUserClient.promote(); 768} 769 770// this class gives us access to SharedBufferServer safely 771// it makes sure the UserClient (and its associated shared memory) 772// won't go away while we're accessing it. 773Layer::ClientRef::Access::Access(const ClientRef& ref) 774 : mControlBlock(0) 775{ 776 Mutex::Autolock _l(ref.mLock); 777 mUserClientStrongRef = ref.mUserClient.promote(); 778 if (mUserClientStrongRef != 0) 779 mControlBlock = ref.mControlBlock; 780} 781 782Layer::ClientRef::Access::~Access() 783{ 784} 785 786// --------------------------------------------------------------------------- 787 788Layer::BufferManager::BufferManager(TextureManager& tm) 789 : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 790 mActiveBufferIndex(-1), mFailover(false) 791{ 792} 793 794Layer::BufferManager::~BufferManager() 795{ 796} 797 798status_t Layer::BufferManager::resize(size_t size, 799 const sp<SurfaceFlinger>& flinger, EGLDisplay dpy) 800{ 801 Mutex::Autolock _l(mLock); 802 803 if (size < mNumBuffers) { 804 // Move the active texture into slot 0 805 BufferData activeBufferData = mBufferData[mActiveBufferIndex]; 806 mBufferData[mActiveBufferIndex] = mBufferData[0]; 807 mBufferData[0] = activeBufferData; 808 mActiveBufferIndex = 0; 809 810 // Free the buffers that are no longer needed. 811 for (size_t i = size; i < mNumBuffers; i++) { 812 mBufferData[i].buffer = 0; 813 814 // Create a message to destroy the textures on SurfaceFlinger's GL 815 // thread. 816 class MessageDestroyTexture : public MessageBase { 817 Image mTexture; 818 EGLDisplay mDpy; 819 public: 820 MessageDestroyTexture(const Image& texture, EGLDisplay dpy) 821 : mTexture(texture), mDpy(dpy) { } 822 virtual bool handler() { 823 status_t err = Layer::BufferManager::destroyTexture( 824 &mTexture, mDpy); 825 LOGE_IF(err<0, "error destroying texture: %d (%s)", 826 mTexture.name, strerror(-err)); 827 return true; // XXX: err == 0; ???? 828 } 829 }; 830 831 MessageDestroyTexture *msg = new MessageDestroyTexture( 832 mBufferData[i].texture, dpy); 833 834 // Don't allow this texture to be cleaned up by 835 // BufferManager::destroy. 836 mBufferData[i].texture.name = -1U; 837 mBufferData[i].texture.image = EGL_NO_IMAGE_KHR; 838 839 // Post the message to the SurfaceFlinger object. 840 flinger->postMessageAsync(msg); 841 } 842 } 843 844 mNumBuffers = size; 845 return NO_ERROR; 846} 847 848// only for debugging 849sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 850 return mBufferData[index].buffer; 851} 852 853status_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 854 BufferData const * const buffers = mBufferData; 855 Mutex::Autolock _l(mLock); 856 mActiveBuffer = buffers[index].buffer; 857 mActiveBufferIndex = index; 858 return NO_ERROR; 859} 860 861size_t Layer::BufferManager::getActiveBufferIndex() const { 862 return mActiveBufferIndex; 863} 864 865Texture Layer::BufferManager::getActiveTexture() const { 866 Texture res; 867 if (mFailover || mActiveBufferIndex<0) { 868 res = mFailoverTexture; 869 } else { 870 static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture; 871 } 872 return res; 873} 874 875sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 876 return mActiveBuffer; 877} 878 879bool Layer::BufferManager::hasActiveBuffer() const { 880 return mActiveBufferIndex >= 0; 881} 882 883sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 884{ 885 BufferData* const buffers = mBufferData; 886 sp<GraphicBuffer> buffer; 887 Mutex::Autolock _l(mLock); 888 buffer = buffers[index].buffer; 889 buffers[index].buffer = 0; 890 return buffer; 891} 892 893status_t Layer::BufferManager::attachBuffer(size_t index, 894 const sp<GraphicBuffer>& buffer) 895{ 896 BufferData* const buffers = mBufferData; 897 Mutex::Autolock _l(mLock); 898 buffers[index].buffer = buffer; 899 buffers[index].texture.dirty = true; 900 return NO_ERROR; 901} 902 903status_t Layer::BufferManager::destroy(EGLDisplay dpy) 904{ 905 BufferData* const buffers = mBufferData; 906 size_t num; 907 { // scope for the lock 908 Mutex::Autolock _l(mLock); 909 num = mNumBuffers; 910 for (size_t i=0 ; i<num ; i++) { 911 buffers[i].buffer = 0; 912 } 913 } 914 for (size_t i=0 ; i<num ; i++) { 915 destroyTexture(&buffers[i].texture, dpy); 916 } 917 destroyTexture(&mFailoverTexture, dpy); 918 return NO_ERROR; 919} 920 921status_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 922 const sp<GraphicBuffer>& buffer) 923{ 924 status_t err = NO_INIT; 925 ssize_t index = mActiveBufferIndex; 926 if (index >= 0) { 927 if (!mFailover) { 928 Image& texture(mBufferData[index].texture); 929 err = mTextureManager.initEglImage(&texture, dpy, buffer); 930 // if EGLImage fails, we switch to regular texture mode, and we 931 // free all resources associated with using EGLImages. 932 if (err == NO_ERROR) { 933 mFailover = false; 934 destroyTexture(&mFailoverTexture, dpy); 935 } else { 936 mFailover = true; 937 const size_t num = mNumBuffers; 938 for (size_t i=0 ; i<num ; i++) { 939 destroyTexture(&mBufferData[i].texture, dpy); 940 } 941 } 942 } else { 943 // we failed once, don't try again 944 err = BAD_VALUE; 945 } 946 } 947 return err; 948} 949 950status_t Layer::BufferManager::loadTexture( 951 const Region& dirty, const GGLSurface& t) 952{ 953 return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 954} 955 956status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 957{ 958 if (tex->name != -1U) { 959 glDeleteTextures(1, &tex->name); 960 tex->name = -1U; 961 } 962 if (tex->image != EGL_NO_IMAGE_KHR) { 963 eglDestroyImageKHR(dpy, tex->image); 964 tex->image = EGL_NO_IMAGE_KHR; 965 } 966 return NO_ERROR; 967} 968 969// --------------------------------------------------------------------------- 970 971Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 972 const sp<Layer>& owner) 973 : Surface(flinger, owner->getIdentity(), owner) 974{ 975} 976 977Layer::SurfaceLayer::~SurfaceLayer() 978{ 979} 980 981sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 982 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 983{ 984 sp<GraphicBuffer> buffer; 985 sp<Layer> owner(getOwner()); 986 if (owner != 0) { 987 /* 988 * requestBuffer() cannot be called from the main thread 989 * as it could cause a dead-lock, since it may have to wait 990 * on conditions updated my the main thread. 991 */ 992 buffer = owner->requestBuffer(index, w, h, format, usage); 993 } 994 return buffer; 995} 996 997status_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 998{ 999 status_t err = DEAD_OBJECT; 1000 sp<Layer> owner(getOwner()); 1001 if (owner != 0) { 1002 /* 1003 * setBufferCount() cannot be called from the main thread 1004 * as it could cause a dead-lock, since it may have to wait 1005 * on conditions updated my the main thread. 1006 */ 1007 err = owner->setBufferCount(bufferCount); 1008 } 1009 return err; 1010} 1011 1012// --------------------------------------------------------------------------- 1013 1014 1015}; // namespace android 1016