Layer.cpp revision 54cc83e8a48c57307cdd40fe4b7e296020490095
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 = const_cast<native_handle_t*>(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 LOGE_IF(err || buffer->handle == 0, 413 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 414 this, index, w, h, strerror(-err)); 415 } else { 416 LOGD_IF(DEBUG_RESIZE, 417 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 418 this, index, w, h, buffer->handle); 419 } 420 421 if (err == NO_ERROR && buffer->handle != 0) { 422 Mutex::Autolock _l(mLock); 423 mBufferManager.attachBuffer(index, buffer); 424 } 425 return buffer; 426} 427 428uint32_t Layer::getEffectiveUsage(uint32_t usage) const 429{ 430 /* 431 * buffers used for software rendering, but h/w composition 432 * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 433 * 434 * buffers used for h/w rendering and h/w composition 435 * are allocated with HW_RENDER | HW_TEXTURE 436 * 437 * buffers used with h/w rendering and either NPOT or no egl_image_ext 438 * are allocated with SW_READ_RARELY | HW_RENDER 439 * 440 */ 441 442 if (mSecure) { 443 // secure buffer, don't store it into the GPU 444 usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 445 GraphicBuffer::USAGE_SW_WRITE_OFTEN; 446 } else { 447 // it's allowed to modify the usage flags here, but generally 448 // the requested flags should be honored. 449 // request EGLImage for all buffers 450 usage |= GraphicBuffer::USAGE_HW_TEXTURE; 451 } 452 return usage; 453} 454 455uint32_t Layer::doTransaction(uint32_t flags) 456{ 457 const Layer::State& front(drawingState()); 458 const Layer::State& temp(currentState()); 459 460 const bool sizeChanged = (front.requested_w != temp.requested_w) || 461 (front.requested_h != temp.requested_h); 462 463 if (sizeChanged) { 464 // the size changed, we need to ask our client to request a new buffer 465 LOGD_IF(DEBUG_RESIZE, 466 "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 467 this, 468 int(temp.requested_w), int(temp.requested_h), 469 int(front.requested_w), int(front.requested_h)); 470 471 if (!isFixedSize()) { 472 // we're being resized and there is a freeze display request, 473 // acquire a freeze lock, so that the screen stays put 474 // until we've redrawn at the new size; this is to avoid 475 // glitches upon orientation changes. 476 if (mFlinger->hasFreezeRequest()) { 477 // if the surface is hidden, don't try to acquire the 478 // freeze lock, since hidden surfaces may never redraw 479 if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 480 mFreezeLock = mFlinger->getFreezeLock(); 481 } 482 } 483 484 // this will make sure LayerBase::doTransaction doesn't update 485 // the drawing state's size 486 Layer::State& editDraw(mDrawingState); 487 editDraw.requested_w = temp.requested_w; 488 editDraw.requested_h = temp.requested_h; 489 490 // record the new size, form this point on, when the client request 491 // a buffer, it'll get the new size. 492 setBufferSize(temp.requested_w, temp.requested_h); 493 494 ClientRef::Access sharedClient(mUserClientRef); 495 SharedBufferServer* lcblk(sharedClient.get()); 496 if (lcblk) { 497 // all buffers need reallocation 498 lcblk->reallocateAll(); 499 } 500 } else { 501 // record the new size 502 setBufferSize(temp.requested_w, temp.requested_h); 503 } 504 } 505 506 if (temp.sequence != front.sequence) { 507 if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 508 // this surface is now hidden, so it shouldn't hold a freeze lock 509 // (it may never redraw, which is fine if it is hidden) 510 mFreezeLock.clear(); 511 } 512 } 513 514 return LayerBase::doTransaction(flags); 515} 516 517void Layer::setBufferSize(uint32_t w, uint32_t h) { 518 Mutex::Autolock _l(mLock); 519 mWidth = w; 520 mHeight = h; 521} 522 523bool Layer::isFixedSize() const { 524 Mutex::Autolock _l(mLock); 525 return mFixedSize; 526} 527 528// ---------------------------------------------------------------------------- 529// pageflip handling... 530// ---------------------------------------------------------------------------- 531 532void Layer::lockPageFlip(bool& recomputeVisibleRegions) 533{ 534 ClientRef::Access sharedClient(mUserClientRef); 535 SharedBufferServer* lcblk(sharedClient.get()); 536 if (!lcblk) { 537 // client died 538 recomputeVisibleRegions = true; 539 return; 540 } 541 542 ssize_t buf = lcblk->retireAndLock(); 543 if (buf == NOT_ENOUGH_DATA) { 544 // NOTE: This is not an error, it simply means there is nothing to 545 // retire. The buffer is locked because we will use it 546 // for composition later in the loop 547 return; 548 } 549 550 if (buf < NO_ERROR) { 551 LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 552 mPostedDirtyRegion.clear(); 553 return; 554 } 555 556 // we retired a buffer, which becomes the new front buffer 557 if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 558 LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 559 mPostedDirtyRegion.clear(); 560 return; 561 } 562 563 sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 564 if (newFrontBuffer != NULL) { 565 // get the dirty region 566 // compute the posted region 567 const Region dirty(lcblk->getDirtyRegion(buf)); 568 mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 569 570 // update the layer size and release freeze-lock 571 const Layer::State& front(drawingState()); 572 if (newFrontBuffer->getWidth() == front.requested_w && 573 newFrontBuffer->getHeight() == front.requested_h) 574 { 575 if ((front.w != front.requested_w) || 576 (front.h != front.requested_h)) 577 { 578 // Here we pretend the transaction happened by updating the 579 // current and drawing states. Drawing state is only accessed 580 // in this thread, no need to have it locked 581 Layer::State& editDraw(mDrawingState); 582 editDraw.w = editDraw.requested_w; 583 editDraw.h = editDraw.requested_h; 584 585 // We also need to update the current state so that we don't 586 // end-up doing too much work during the next transaction. 587 // NOTE: We actually don't need hold the transaction lock here 588 // because State::w and State::h are only accessed from 589 // this thread 590 Layer::State& editTemp(currentState()); 591 editTemp.w = editDraw.w; 592 editTemp.h = editDraw.h; 593 594 // recompute visible region 595 recomputeVisibleRegions = true; 596 } 597 598 // we now have the correct size, unfreeze the screen 599 mFreezeLock.clear(); 600 } 601 602 // get the crop region 603 setBufferCrop( lcblk->getCrop(buf) ); 604 605 // get the transformation 606 setBufferTransform( lcblk->getTransform(buf) ); 607 608 } else { 609 // this should not happen unless we ran out of memory while 610 // allocating the buffer. we're hoping that things will get back 611 // to normal the next time the app tries to draw into this buffer. 612 // meanwhile, pretend the screen didn't update. 613 mPostedDirtyRegion.clear(); 614 } 615 616 if (lcblk->getQueuedCount()) { 617 // signal an event if we have more buffers waiting 618 mFlinger->signalEvent(); 619 } 620 621 /* a buffer was posted, so we need to call reloadTexture(), which 622 * will update our internal data structures (eg: EGLImageKHR or 623 * texture names). we need to do this even if mPostedDirtyRegion is 624 * empty -- it's orthogonal to the fact that a new buffer was posted, 625 * for instance, a degenerate case could be that the user did an empty 626 * update but repainted the buffer with appropriate content (after a 627 * resize for instance). 628 */ 629 reloadTexture( mPostedDirtyRegion ); 630} 631 632void Layer::unlockPageFlip( 633 const Transform& planeTransform, Region& outDirtyRegion) 634{ 635 Region dirtyRegion(mPostedDirtyRegion); 636 if (!dirtyRegion.isEmpty()) { 637 mPostedDirtyRegion.clear(); 638 // The dirty region is given in the layer's coordinate space 639 // transform the dirty region by the surface's transformation 640 // and the global transformation. 641 const Layer::State& s(drawingState()); 642 const Transform tr(planeTransform * s.transform); 643 dirtyRegion = tr.transform(dirtyRegion); 644 645 // At this point, the dirty region is in screen space. 646 // Make sure it's constrained by the visible region (which 647 // is in screen space as well). 648 dirtyRegion.andSelf(visibleRegionScreen); 649 outDirtyRegion.orSelf(dirtyRegion); 650 } 651 if (visibleRegionScreen.isEmpty()) { 652 // an invisible layer should not hold a freeze-lock 653 // (because it may never be updated and therefore never release it) 654 mFreezeLock.clear(); 655 } 656} 657 658void Layer::finishPageFlip() 659{ 660 ClientRef::Access sharedClient(mUserClientRef); 661 SharedBufferServer* lcblk(sharedClient.get()); 662 if (lcblk) { 663 int buf = mBufferManager.getActiveBufferIndex(); 664 if (buf >= 0) { 665 status_t err = lcblk->unlock( buf ); 666 LOGE_IF(err!=NO_ERROR, 667 "layer %p, buffer=%d wasn't locked!", 668 this, buf); 669 } 670 } 671} 672 673 674void Layer::dump(String8& result, char* buffer, size_t SIZE) const 675{ 676 LayerBaseClient::dump(result, buffer, SIZE); 677 678 ClientRef::Access sharedClient(mUserClientRef); 679 SharedBufferServer* lcblk(sharedClient.get()); 680 uint32_t totalTime = 0; 681 if (lcblk) { 682 SharedBufferStack::Statistics stats = lcblk->getStats(); 683 totalTime= stats.totalTime; 684 result.append( lcblk->dump(" ") ); 685 } 686 687 sp<const GraphicBuffer> buf0(getBuffer(0)); 688 sp<const GraphicBuffer> buf1(getBuffer(1)); 689 uint32_t w0=0, h0=0, s0=0; 690 uint32_t w1=0, h1=0, s1=0; 691 if (buf0 != 0) { 692 w0 = buf0->getWidth(); 693 h0 = buf0->getHeight(); 694 s0 = buf0->getStride(); 695 } 696 if (buf1 != 0) { 697 w1 = buf1->getWidth(); 698 h1 = buf1->getHeight(); 699 s1 = buf1->getStride(); 700 } 701 snprintf(buffer, SIZE, 702 " " 703 "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 704 " freezeLock=%p, dq-q-time=%u us\n", 705 mFormat, w0, h0, s0, w1, h1, s1, 706 getFreezeLock().get(), totalTime); 707 708 result.append(buffer); 709} 710 711// --------------------------------------------------------------------------- 712 713Layer::ClientRef::ClientRef() 714 : mControlBlock(0), mToken(-1) { 715} 716 717Layer::ClientRef::~ClientRef() { 718} 719 720int32_t Layer::ClientRef::getToken() const { 721 Mutex::Autolock _l(mLock); 722 return mToken; 723} 724 725sp<UserClient> Layer::ClientRef::getClient() const { 726 Mutex::Autolock _l(mLock); 727 return mUserClient.promote(); 728} 729 730status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 731 const sp<SharedBufferServer>& sharedClient, int32_t token) { 732 Mutex::Autolock _l(mLock); 733 734 { // scope for strong mUserClient reference 735 sp<UserClient> userClient(mUserClient.promote()); 736 if (mUserClient != 0 && mControlBlock != 0) { 737 mControlBlock->setStatus(NO_INIT); 738 } 739 } 740 741 mUserClient = uc; 742 mToken = token; 743 mControlBlock = sharedClient; 744 return NO_ERROR; 745} 746 747sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 748 return mUserClient.promote(); 749} 750 751// this class gives us access to SharedBufferServer safely 752// it makes sure the UserClient (and its associated shared memory) 753// won't go away while we're accessing it. 754Layer::ClientRef::Access::Access(const ClientRef& ref) 755 : mControlBlock(0) 756{ 757 Mutex::Autolock _l(ref.mLock); 758 mUserClientStrongRef = ref.mUserClient.promote(); 759 if (mUserClientStrongRef != 0) 760 mControlBlock = ref.mControlBlock; 761} 762 763Layer::ClientRef::Access::~Access() 764{ 765} 766 767// --------------------------------------------------------------------------- 768 769Layer::BufferManager::BufferManager(TextureManager& tm) 770 : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 771 mActiveBuffer(-1), mFailover(false) 772{ 773} 774 775Layer::BufferManager::~BufferManager() 776{ 777} 778 779status_t Layer::BufferManager::resize(size_t size, 780 const sp<SurfaceFlinger>& flinger, EGLDisplay dpy) 781{ 782 Mutex::Autolock _l(mLock); 783 784 if (size < mNumBuffers) { 785 // Move the active texture into slot 0 786 BufferData activeBufferData = mBufferData[mActiveBuffer]; 787 mBufferData[mActiveBuffer] = mBufferData[0]; 788 mBufferData[0] = activeBufferData; 789 mActiveBuffer = 0; 790 791 // Free the buffers that are no longer needed. 792 for (size_t i = size; i < mNumBuffers; i++) { 793 mBufferData[i].buffer = 0; 794 795 // Create a message to destroy the textures on SurfaceFlinger's GL 796 // thread. 797 class MessageDestroyTexture : public MessageBase { 798 Image mTexture; 799 EGLDisplay mDpy; 800 public: 801 MessageDestroyTexture(const Image& texture, EGLDisplay dpy) 802 : mTexture(texture), mDpy(dpy) { } 803 virtual bool handler() { 804 status_t err = Layer::BufferManager::destroyTexture( 805 &mTexture, mDpy); 806 LOGE_IF(err<0, "error destroying texture: %d (%s)", 807 mTexture.name, strerror(-err)); 808 return true; // XXX: err == 0; ???? 809 } 810 }; 811 812 MessageDestroyTexture *msg = new MessageDestroyTexture( 813 mBufferData[i].texture, dpy); 814 815 // Don't allow this texture to be cleaned up by 816 // BufferManager::destroy. 817 mBufferData[i].texture.name = -1U; 818 mBufferData[i].texture.image = EGL_NO_IMAGE_KHR; 819 820 // Post the message to the SurfaceFlinger object. 821 flinger->postMessageAsync(msg); 822 } 823 } 824 825 mNumBuffers = size; 826 return NO_ERROR; 827} 828 829// only for debugging 830sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 831 return mBufferData[index].buffer; 832} 833 834status_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 835 mActiveBuffer = index; 836 return NO_ERROR; 837} 838 839size_t Layer::BufferManager::getActiveBufferIndex() const { 840 return mActiveBuffer; 841} 842 843Texture Layer::BufferManager::getActiveTexture() const { 844 Texture res; 845 if (mFailover || mActiveBuffer<0) { 846 res = mFailoverTexture; 847 } else { 848 static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; 849 } 850 return res; 851} 852 853sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 854 sp<GraphicBuffer> result; 855 const ssize_t activeBuffer = mActiveBuffer; 856 if (activeBuffer >= 0) { 857 BufferData const * const buffers = mBufferData; 858 Mutex::Autolock _l(mLock); 859 result = buffers[activeBuffer].buffer; 860 } 861 return result; 862} 863 864sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 865{ 866 BufferData* const buffers = mBufferData; 867 sp<GraphicBuffer> buffer; 868 Mutex::Autolock _l(mLock); 869 buffer = buffers[index].buffer; 870 buffers[index].buffer = 0; 871 return buffer; 872} 873 874status_t Layer::BufferManager::attachBuffer(size_t index, 875 const sp<GraphicBuffer>& buffer) 876{ 877 BufferData* const buffers = mBufferData; 878 Mutex::Autolock _l(mLock); 879 buffers[index].buffer = buffer; 880 buffers[index].texture.dirty = true; 881 return NO_ERROR; 882} 883 884status_t Layer::BufferManager::destroy(EGLDisplay dpy) 885{ 886 BufferData* const buffers = mBufferData; 887 size_t num; 888 { // scope for the lock 889 Mutex::Autolock _l(mLock); 890 num = mNumBuffers; 891 for (size_t i=0 ; i<num ; i++) { 892 buffers[i].buffer = 0; 893 } 894 } 895 for (size_t i=0 ; i<num ; i++) { 896 destroyTexture(&buffers[i].texture, dpy); 897 } 898 destroyTexture(&mFailoverTexture, dpy); 899 return NO_ERROR; 900} 901 902status_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 903 const sp<GraphicBuffer>& buffer) 904{ 905 status_t err = NO_INIT; 906 ssize_t index = mActiveBuffer; 907 if (index >= 0) { 908 if (!mFailover) { 909 Image& texture(mBufferData[index].texture); 910 err = mTextureManager.initEglImage(&texture, dpy, buffer); 911 // if EGLImage fails, we switch to regular texture mode, and we 912 // free all resources associated with using EGLImages. 913 if (err == NO_ERROR) { 914 mFailover = false; 915 destroyTexture(&mFailoverTexture, dpy); 916 } else { 917 mFailover = true; 918 const size_t num = mNumBuffers; 919 for (size_t i=0 ; i<num ; i++) { 920 destroyTexture(&mBufferData[i].texture, dpy); 921 } 922 } 923 } else { 924 // we failed once, don't try again 925 err = BAD_VALUE; 926 } 927 } 928 return err; 929} 930 931status_t Layer::BufferManager::loadTexture( 932 const Region& dirty, const GGLSurface& t) 933{ 934 return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 935} 936 937status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 938{ 939 if (tex->name != -1U) { 940 glDeleteTextures(1, &tex->name); 941 tex->name = -1U; 942 } 943 if (tex->image != EGL_NO_IMAGE_KHR) { 944 eglDestroyImageKHR(dpy, tex->image); 945 tex->image = EGL_NO_IMAGE_KHR; 946 } 947 return NO_ERROR; 948} 949 950// --------------------------------------------------------------------------- 951 952Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 953 const sp<Layer>& owner) 954 : Surface(flinger, owner->getIdentity(), owner) 955{ 956} 957 958Layer::SurfaceLayer::~SurfaceLayer() 959{ 960} 961 962sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 963 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 964{ 965 sp<GraphicBuffer> buffer; 966 sp<Layer> owner(getOwner()); 967 if (owner != 0) { 968 /* 969 * requestBuffer() cannot be called from the main thread 970 * as it could cause a dead-lock, since it may have to wait 971 * on conditions updated my the main thread. 972 */ 973 buffer = owner->requestBuffer(index, w, h, format, usage); 974 } 975 return buffer; 976} 977 978status_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 979{ 980 status_t err = DEAD_OBJECT; 981 sp<Layer> owner(getOwner()); 982 if (owner != 0) { 983 /* 984 * setBufferCount() cannot be called from the main thread 985 * as it could cause a dead-lock, since it may have to wait 986 * on conditions updated my the main thread. 987 */ 988 err = owner->setBufferCount(bufferCount); 989 } 990 return err; 991} 992 993// --------------------------------------------------------------------------- 994 995 996}; // namespace android 997