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