Layer.cpp revision 000ca8fa9a1a92aa2f132ba41d11ece6d01cdadd
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 299 status_t err = NO_ERROR; 300 uint32_t w, h, f; 301 { // scope for the lock 302 Mutex::Autolock _l(mLock); 303 const bool fixedSizeChanged = mFixedSize != (reqWidth && reqHeight); 304 const bool formatChanged = mReqFormat != reqFormat; 305 mReqWidth = reqWidth; 306 mReqHeight = reqHeight; 307 mReqFormat = reqFormat; 308 mFixedSize = reqWidth && reqHeight; 309 w = reqWidth ? reqWidth : mWidth; 310 h = reqHeight ? reqHeight : mHeight; 311 f = reqFormat ? reqFormat : mFormat; 312 if (fixedSizeChanged || formatChanged) { 313 lcblk->reallocateAllExcept(index); 314 } 315 } 316 317 // here we have to reallocate a new buffer because the buffer could be 318 // used as the front buffer, or by a client in our process 319 // (eg: status bar), and we can't release the handle under its feet. 320 const uint32_t effectiveUsage = getEffectiveUsage(usage); 321 buffer = new GraphicBuffer(w, h, f, effectiveUsage); 322 err = buffer->initCheck(); 323 324 if (err || buffer->handle == 0) { 325 LOGE_IF(err || buffer->handle == 0, 326 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 327 this, index, w, h, strerror(-err)); 328 } else { 329 LOGD_IF(DEBUG_RESIZE, 330 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 331 this, index, w, h, buffer->handle); 332 } 333 334 if (err == NO_ERROR && buffer->handle != 0) { 335 Mutex::Autolock _l(mLock); 336 mBufferManager.attachBuffer(index, buffer); 337 } 338 return buffer; 339} 340 341uint32_t Layer::getEffectiveUsage(uint32_t usage) const 342{ 343 /* 344 * buffers used for software rendering, but h/w composition 345 * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 346 * 347 * buffers used for h/w rendering and h/w composition 348 * are allocated with HW_RENDER | HW_TEXTURE 349 * 350 * buffers used with h/w rendering and either NPOT or no egl_image_ext 351 * are allocated with SW_READ_RARELY | HW_RENDER 352 * 353 */ 354 355 if (mSecure) { 356 // secure buffer, don't store it into the GPU 357 usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 358 GraphicBuffer::USAGE_SW_WRITE_OFTEN; 359 } else { 360 // it's allowed to modify the usage flags here, but generally 361 // the requested flags should be honored. 362 // request EGLImage for all buffers 363 usage |= GraphicBuffer::USAGE_HW_TEXTURE; 364 } 365 return usage; 366} 367 368uint32_t Layer::doTransaction(uint32_t flags) 369{ 370 const Layer::State& front(drawingState()); 371 const Layer::State& temp(currentState()); 372 373 const bool sizeChanged = (front.requested_w != temp.requested_w) || 374 (front.requested_h != temp.requested_h); 375 376 if (sizeChanged) { 377 // the size changed, we need to ask our client to request a new buffer 378 LOGD_IF(DEBUG_RESIZE, 379 "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 380 this, 381 int(temp.requested_w), int(temp.requested_h), 382 int(front.requested_w), int(front.requested_h)); 383 384 if (!isFixedSize()) { 385 // we're being resized and there is a freeze display request, 386 // acquire a freeze lock, so that the screen stays put 387 // until we've redrawn at the new size; this is to avoid 388 // glitches upon orientation changes. 389 if (mFlinger->hasFreezeRequest()) { 390 // if the surface is hidden, don't try to acquire the 391 // freeze lock, since hidden surfaces may never redraw 392 if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 393 mFreezeLock = mFlinger->getFreezeLock(); 394 } 395 } 396 397 // this will make sure LayerBase::doTransaction doesn't update 398 // the drawing state's size 399 Layer::State& editDraw(mDrawingState); 400 editDraw.requested_w = temp.requested_w; 401 editDraw.requested_h = temp.requested_h; 402 403 // record the new size, form this point on, when the client request 404 // a buffer, it'll get the new size. 405 setBufferSize(temp.requested_w, temp.requested_h); 406 407 ClientRef::Access sharedClient(mUserClientRef); 408 SharedBufferServer* lcblk(sharedClient.get()); 409 if (lcblk) { 410 // all buffers need reallocation 411 lcblk->reallocateAll(); 412 } 413 } else { 414 // record the new size 415 setBufferSize(temp.requested_w, temp.requested_h); 416 } 417 } 418 419 if (temp.sequence != front.sequence) { 420 if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 421 // this surface is now hidden, so it shouldn't hold a freeze lock 422 // (it may never redraw, which is fine if it is hidden) 423 mFreezeLock.clear(); 424 } 425 } 426 427 return LayerBase::doTransaction(flags); 428} 429 430void Layer::setBufferSize(uint32_t w, uint32_t h) { 431 Mutex::Autolock _l(mLock); 432 mWidth = w; 433 mHeight = h; 434} 435 436bool Layer::isFixedSize() const { 437 Mutex::Autolock _l(mLock); 438 return mFixedSize; 439} 440 441// ---------------------------------------------------------------------------- 442// pageflip handling... 443// ---------------------------------------------------------------------------- 444 445void Layer::lockPageFlip(bool& recomputeVisibleRegions) 446{ 447 ClientRef::Access sharedClient(mUserClientRef); 448 SharedBufferServer* lcblk(sharedClient.get()); 449 if (!lcblk) { 450 // client died 451 recomputeVisibleRegions = true; 452 return; 453 } 454 455 ssize_t buf = lcblk->retireAndLock(); 456 if (buf == NOT_ENOUGH_DATA) { 457 // NOTE: This is not an error, it simply means there is nothing to 458 // retire. The buffer is locked because we will use it 459 // for composition later in the loop 460 return; 461 } 462 463 if (buf < NO_ERROR) { 464 LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 465 mPostedDirtyRegion.clear(); 466 return; 467 } 468 469 // we retired a buffer, which becomes the new front buffer 470 if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) { 471 LOGE("retireAndLock() buffer index (%d) out of range", int(buf)); 472 mPostedDirtyRegion.clear(); 473 return; 474 } 475 476 // get the dirty region 477 sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 478 if (newFrontBuffer != NULL) { 479 // compute the posted region 480 const Region dirty(lcblk->getDirtyRegion(buf)); 481 mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() ); 482 483 // update the layer size and release freeze-lock 484 const Layer::State& front(drawingState()); 485 if (newFrontBuffer->getWidth() == front.requested_w && 486 newFrontBuffer->getHeight() == front.requested_h) 487 { 488 if ((front.w != front.requested_w) || 489 (front.h != front.requested_h)) 490 { 491 // Here we pretend the transaction happened by updating the 492 // current and drawing states. Drawing state is only accessed 493 // in this thread, no need to have it locked 494 Layer::State& editDraw(mDrawingState); 495 editDraw.w = editDraw.requested_w; 496 editDraw.h = editDraw.requested_h; 497 498 // We also need to update the current state so that we don't 499 // end-up doing too much work during the next transaction. 500 // NOTE: We actually don't need hold the transaction lock here 501 // because State::w and State::h are only accessed from 502 // this thread 503 Layer::State& editTemp(currentState()); 504 editTemp.w = editDraw.w; 505 editTemp.h = editDraw.h; 506 507 // recompute visible region 508 recomputeVisibleRegions = true; 509 } 510 511 // we now have the correct size, unfreeze the screen 512 mFreezeLock.clear(); 513 } 514 } else { 515 // this should not happen unless we ran out of memory while 516 // allocating the buffer. we're hoping that things will get back 517 // to normal the next time the app tries to draw into this buffer. 518 // meanwhile, pretend the screen didn't update. 519 mPostedDirtyRegion.clear(); 520 } 521 522 if (lcblk->getQueuedCount()) { 523 // signal an event if we have more buffers waiting 524 mFlinger->signalEvent(); 525 } 526 527 /* a buffer was posted, so we need to call reloadTexture(), which 528 * will update our internal data structures (eg: EGLImageKHR or 529 * texture names). we need to do this even if mPostedDirtyRegion is 530 * empty -- it's orthogonal to the fact that a new buffer was posted, 531 * for instance, a degenerate case could be that the user did an empty 532 * update but repainted the buffer with appropriate content (after a 533 * resize for instance). 534 */ 535 reloadTexture( mPostedDirtyRegion ); 536} 537 538void Layer::unlockPageFlip( 539 const Transform& planeTransform, Region& outDirtyRegion) 540{ 541 Region dirtyRegion(mPostedDirtyRegion); 542 if (!dirtyRegion.isEmpty()) { 543 mPostedDirtyRegion.clear(); 544 // The dirty region is given in the layer's coordinate space 545 // transform the dirty region by the surface's transformation 546 // and the global transformation. 547 const Layer::State& s(drawingState()); 548 const Transform tr(planeTransform * s.transform); 549 dirtyRegion = tr.transform(dirtyRegion); 550 551 // At this point, the dirty region is in screen space. 552 // Make sure it's constrained by the visible region (which 553 // is in screen space as well). 554 dirtyRegion.andSelf(visibleRegionScreen); 555 outDirtyRegion.orSelf(dirtyRegion); 556 } 557 if (visibleRegionScreen.isEmpty()) { 558 // an invisible layer should not hold a freeze-lock 559 // (because it may never be updated and therefore never release it) 560 mFreezeLock.clear(); 561 } 562} 563 564void Layer::finishPageFlip() 565{ 566 ClientRef::Access sharedClient(mUserClientRef); 567 SharedBufferServer* lcblk(sharedClient.get()); 568 if (lcblk) { 569 int buf = mBufferManager.getActiveBufferIndex(); 570 if (buf >= 0) { 571 status_t err = lcblk->unlock( buf ); 572 LOGE_IF(err!=NO_ERROR, 573 "layer %p, buffer=%d wasn't locked!", 574 this, buf); 575 } 576 } 577} 578 579 580void Layer::dump(String8& result, char* buffer, size_t SIZE) const 581{ 582 LayerBaseClient::dump(result, buffer, SIZE); 583 584 ClientRef::Access sharedClient(mUserClientRef); 585 SharedBufferServer* lcblk(sharedClient.get()); 586 uint32_t totalTime = 0; 587 if (lcblk) { 588 SharedBufferStack::Statistics stats = lcblk->getStats(); 589 totalTime= stats.totalTime; 590 result.append( lcblk->dump(" ") ); 591 } 592 593 sp<const GraphicBuffer> buf0(getBuffer(0)); 594 sp<const GraphicBuffer> buf1(getBuffer(1)); 595 uint32_t w0=0, h0=0, s0=0; 596 uint32_t w1=0, h1=0, s1=0; 597 if (buf0 != 0) { 598 w0 = buf0->getWidth(); 599 h0 = buf0->getHeight(); 600 s0 = buf0->getStride(); 601 } 602 if (buf1 != 0) { 603 w1 = buf1->getWidth(); 604 h1 = buf1->getHeight(); 605 s1 = buf1->getStride(); 606 } 607 snprintf(buffer, SIZE, 608 " " 609 "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 610 " freezeLock=%p, dq-q-time=%u us\n", 611 mFormat, w0, h0, s0, w1, h1, s1, 612 getFreezeLock().get(), totalTime); 613 614 result.append(buffer); 615} 616 617// --------------------------------------------------------------------------- 618 619Layer::ClientRef::ClientRef() 620 : mControlBlock(0), mToken(-1) { 621} 622 623Layer::ClientRef::~ClientRef() { 624} 625 626int32_t Layer::ClientRef::getToken() const { 627 Mutex::Autolock _l(mLock); 628 return mToken; 629} 630 631sp<UserClient> Layer::ClientRef::getClient() const { 632 Mutex::Autolock _l(mLock); 633 return mUserClient.promote(); 634} 635 636status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 637 const sp<SharedBufferServer>& sharedClient, int32_t token) { 638 Mutex::Autolock _l(mLock); 639 640 { // scope for strong mUserClient reference 641 sp<UserClient> userClient(mUserClient.promote()); 642 if (mUserClient != 0 && mControlBlock != 0) { 643 mControlBlock->setStatus(NO_INIT); 644 } 645 } 646 647 mUserClient = uc; 648 mToken = token; 649 mControlBlock = sharedClient; 650 return NO_ERROR; 651} 652 653sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 654 return mUserClient.promote(); 655} 656 657// this class gives us access to SharedBufferServer safely 658// it makes sure the UserClient (and its associated shared memory) 659// won't go away while we're accessing it. 660Layer::ClientRef::Access::Access(const ClientRef& ref) 661 : mControlBlock(0) 662{ 663 Mutex::Autolock _l(ref.mLock); 664 mUserClientStrongRef = ref.mUserClient.promote(); 665 if (mUserClientStrongRef != 0) 666 mControlBlock = ref.mControlBlock; 667} 668 669Layer::ClientRef::Access::~Access() 670{ 671} 672 673// --------------------------------------------------------------------------- 674 675Layer::BufferManager::BufferManager(TextureManager& tm) 676 : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 677 mActiveBuffer(-1), mFailover(false) 678{ 679} 680 681Layer::BufferManager::~BufferManager() 682{ 683} 684 685status_t Layer::BufferManager::resize(size_t size) 686{ 687 Mutex::Autolock _l(mLock); 688 mNumBuffers = size; 689 return NO_ERROR; 690} 691 692// only for debugging 693sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 694 return mBufferData[index].buffer; 695} 696 697status_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 698 mActiveBuffer = index; 699 return NO_ERROR; 700} 701 702size_t Layer::BufferManager::getActiveBufferIndex() const { 703 return mActiveBuffer; 704} 705 706Texture Layer::BufferManager::getActiveTexture() const { 707 Texture res; 708 if (mFailover || mActiveBuffer<0) { 709 res = mFailoverTexture; 710 } else { 711 static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; 712 } 713 return res; 714} 715 716sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 717 sp<GraphicBuffer> result; 718 const ssize_t activeBuffer = mActiveBuffer; 719 if (activeBuffer >= 0) { 720 BufferData const * const buffers = mBufferData; 721 Mutex::Autolock _l(mLock); 722 result = buffers[activeBuffer].buffer; 723 } 724 return result; 725} 726 727sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 728{ 729 BufferData* const buffers = mBufferData; 730 sp<GraphicBuffer> buffer; 731 Mutex::Autolock _l(mLock); 732 buffer = buffers[index].buffer; 733 buffers[index].buffer = 0; 734 return buffer; 735} 736 737status_t Layer::BufferManager::attachBuffer(size_t index, 738 const sp<GraphicBuffer>& buffer) 739{ 740 BufferData* const buffers = mBufferData; 741 Mutex::Autolock _l(mLock); 742 buffers[index].buffer = buffer; 743 buffers[index].texture.dirty = true; 744 return NO_ERROR; 745} 746 747status_t Layer::BufferManager::destroy(EGLDisplay dpy) 748{ 749 BufferData* const buffers = mBufferData; 750 size_t num; 751 { // scope for the lock 752 Mutex::Autolock _l(mLock); 753 num = mNumBuffers; 754 for (size_t i=0 ; i<num ; i++) { 755 buffers[i].buffer = 0; 756 } 757 } 758 for (size_t i=0 ; i<num ; i++) { 759 destroyTexture(&buffers[i].texture, dpy); 760 } 761 destroyTexture(&mFailoverTexture, dpy); 762 return NO_ERROR; 763} 764 765status_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 766 const sp<GraphicBuffer>& buffer) 767{ 768 status_t err = NO_INIT; 769 ssize_t index = mActiveBuffer; 770 if (index >= 0) { 771 if (!mFailover) { 772 Image& texture(mBufferData[index].texture); 773 err = mTextureManager.initEglImage(&texture, dpy, buffer); 774 // if EGLImage fails, we switch to regular texture mode, and we 775 // free all resources associated with using EGLImages. 776 if (err == NO_ERROR) { 777 mFailover = false; 778 destroyTexture(&mFailoverTexture, dpy); 779 } else { 780 mFailover = true; 781 const size_t num = mNumBuffers; 782 for (size_t i=0 ; i<num ; i++) { 783 destroyTexture(&mBufferData[i].texture, dpy); 784 } 785 } 786 } else { 787 // we failed once, don't try again 788 err = BAD_VALUE; 789 } 790 } 791 return err; 792} 793 794status_t Layer::BufferManager::loadTexture( 795 const Region& dirty, const GGLSurface& t) 796{ 797 return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 798} 799 800status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 801{ 802 if (tex->name != -1U) { 803 glDeleteTextures(1, &tex->name); 804 tex->name = -1U; 805 } 806 if (tex->image != EGL_NO_IMAGE_KHR) { 807 eglDestroyImageKHR(dpy, tex->image); 808 tex->image = EGL_NO_IMAGE_KHR; 809 } 810 return NO_ERROR; 811} 812 813// --------------------------------------------------------------------------- 814 815Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 816 const sp<Layer>& owner) 817 : Surface(flinger, owner->getIdentity(), owner) 818{ 819} 820 821Layer::SurfaceLayer::~SurfaceLayer() 822{ 823} 824 825sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 826 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 827{ 828 sp<GraphicBuffer> buffer; 829 sp<Layer> owner(getOwner()); 830 if (owner != 0) { 831 /* 832 * requestBuffer() cannot be called from the main thread 833 * as it could cause a dead-lock, since it may have to wait 834 * on conditions updated my the main thread. 835 */ 836 buffer = owner->requestBuffer(index, w, h, format, usage); 837 } 838 return buffer; 839} 840 841status_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 842{ 843 status_t err = DEAD_OBJECT; 844 sp<Layer> owner(getOwner()); 845 if (owner != 0) { 846 /* 847 * setBufferCount() cannot be called from the main thread 848 * as it could cause a dead-lock, since it may have to wait 849 * on conditions updated my the main thread. 850 */ 851 err = owner->setBufferCount(bufferCount); 852 } 853 return err; 854} 855 856// --------------------------------------------------------------------------- 857 858 859}; // namespace android 860