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