Layer.cpp revision b661d66013b9803c50dc78ca0247ac39caef443a
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 sp<GraphicBuffer> newFrontBuffer(getBuffer(buf)); 477 if (newFrontBuffer != NULL) { 478 // get the dirty region 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 515 // get the crop region 516 setBufferCrop( lcblk->getCrop(buf) ); 517 518 // get the transformation 519 setBufferTransform( lcblk->getTransform(buf) ); 520 521 } else { 522 // this should not happen unless we ran out of memory while 523 // allocating the buffer. we're hoping that things will get back 524 // to normal the next time the app tries to draw into this buffer. 525 // meanwhile, pretend the screen didn't update. 526 mPostedDirtyRegion.clear(); 527 } 528 529 if (lcblk->getQueuedCount()) { 530 // signal an event if we have more buffers waiting 531 mFlinger->signalEvent(); 532 } 533 534 /* a buffer was posted, so we need to call reloadTexture(), which 535 * will update our internal data structures (eg: EGLImageKHR or 536 * texture names). we need to do this even if mPostedDirtyRegion is 537 * empty -- it's orthogonal to the fact that a new buffer was posted, 538 * for instance, a degenerate case could be that the user did an empty 539 * update but repainted the buffer with appropriate content (after a 540 * resize for instance). 541 */ 542 reloadTexture( mPostedDirtyRegion ); 543} 544 545void Layer::unlockPageFlip( 546 const Transform& planeTransform, Region& outDirtyRegion) 547{ 548 Region dirtyRegion(mPostedDirtyRegion); 549 if (!dirtyRegion.isEmpty()) { 550 mPostedDirtyRegion.clear(); 551 // The dirty region is given in the layer's coordinate space 552 // transform the dirty region by the surface's transformation 553 // and the global transformation. 554 const Layer::State& s(drawingState()); 555 const Transform tr(planeTransform * s.transform); 556 dirtyRegion = tr.transform(dirtyRegion); 557 558 // At this point, the dirty region is in screen space. 559 // Make sure it's constrained by the visible region (which 560 // is in screen space as well). 561 dirtyRegion.andSelf(visibleRegionScreen); 562 outDirtyRegion.orSelf(dirtyRegion); 563 } 564 if (visibleRegionScreen.isEmpty()) { 565 // an invisible layer should not hold a freeze-lock 566 // (because it may never be updated and therefore never release it) 567 mFreezeLock.clear(); 568 } 569} 570 571void Layer::finishPageFlip() 572{ 573 ClientRef::Access sharedClient(mUserClientRef); 574 SharedBufferServer* lcblk(sharedClient.get()); 575 if (lcblk) { 576 int buf = mBufferManager.getActiveBufferIndex(); 577 if (buf >= 0) { 578 status_t err = lcblk->unlock( buf ); 579 LOGE_IF(err!=NO_ERROR, 580 "layer %p, buffer=%d wasn't locked!", 581 this, buf); 582 } 583 } 584} 585 586 587void Layer::dump(String8& result, char* buffer, size_t SIZE) const 588{ 589 LayerBaseClient::dump(result, buffer, SIZE); 590 591 ClientRef::Access sharedClient(mUserClientRef); 592 SharedBufferServer* lcblk(sharedClient.get()); 593 uint32_t totalTime = 0; 594 if (lcblk) { 595 SharedBufferStack::Statistics stats = lcblk->getStats(); 596 totalTime= stats.totalTime; 597 result.append( lcblk->dump(" ") ); 598 } 599 600 sp<const GraphicBuffer> buf0(getBuffer(0)); 601 sp<const GraphicBuffer> buf1(getBuffer(1)); 602 uint32_t w0=0, h0=0, s0=0; 603 uint32_t w1=0, h1=0, s1=0; 604 if (buf0 != 0) { 605 w0 = buf0->getWidth(); 606 h0 = buf0->getHeight(); 607 s0 = buf0->getStride(); 608 } 609 if (buf1 != 0) { 610 w1 = buf1->getWidth(); 611 h1 = buf1->getHeight(); 612 s1 = buf1->getStride(); 613 } 614 snprintf(buffer, SIZE, 615 " " 616 "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u]," 617 " freezeLock=%p, dq-q-time=%u us\n", 618 mFormat, w0, h0, s0, w1, h1, s1, 619 getFreezeLock().get(), totalTime); 620 621 result.append(buffer); 622} 623 624// --------------------------------------------------------------------------- 625 626Layer::ClientRef::ClientRef() 627 : mControlBlock(0), mToken(-1) { 628} 629 630Layer::ClientRef::~ClientRef() { 631} 632 633int32_t Layer::ClientRef::getToken() const { 634 Mutex::Autolock _l(mLock); 635 return mToken; 636} 637 638sp<UserClient> Layer::ClientRef::getClient() const { 639 Mutex::Autolock _l(mLock); 640 return mUserClient.promote(); 641} 642 643status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, 644 const sp<SharedBufferServer>& sharedClient, int32_t token) { 645 Mutex::Autolock _l(mLock); 646 647 { // scope for strong mUserClient reference 648 sp<UserClient> userClient(mUserClient.promote()); 649 if (mUserClient != 0 && mControlBlock != 0) { 650 mControlBlock->setStatus(NO_INIT); 651 } 652 } 653 654 mUserClient = uc; 655 mToken = token; 656 mControlBlock = sharedClient; 657 return NO_ERROR; 658} 659 660sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const { 661 return mUserClient.promote(); 662} 663 664// this class gives us access to SharedBufferServer safely 665// it makes sure the UserClient (and its associated shared memory) 666// won't go away while we're accessing it. 667Layer::ClientRef::Access::Access(const ClientRef& ref) 668 : mControlBlock(0) 669{ 670 Mutex::Autolock _l(ref.mLock); 671 mUserClientStrongRef = ref.mUserClient.promote(); 672 if (mUserClientStrongRef != 0) 673 mControlBlock = ref.mControlBlock; 674} 675 676Layer::ClientRef::Access::~Access() 677{ 678} 679 680// --------------------------------------------------------------------------- 681 682Layer::BufferManager::BufferManager(TextureManager& tm) 683 : mNumBuffers(NUM_BUFFERS), mTextureManager(tm), 684 mActiveBuffer(-1), mFailover(false) 685{ 686} 687 688Layer::BufferManager::~BufferManager() 689{ 690} 691 692status_t Layer::BufferManager::resize(size_t size) 693{ 694 Mutex::Autolock _l(mLock); 695 mNumBuffers = size; 696 return NO_ERROR; 697} 698 699// only for debugging 700sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const { 701 return mBufferData[index].buffer; 702} 703 704status_t Layer::BufferManager::setActiveBufferIndex(size_t index) { 705 mActiveBuffer = index; 706 return NO_ERROR; 707} 708 709size_t Layer::BufferManager::getActiveBufferIndex() const { 710 return mActiveBuffer; 711} 712 713Texture Layer::BufferManager::getActiveTexture() const { 714 Texture res; 715 if (mFailover || mActiveBuffer<0) { 716 res = mFailoverTexture; 717 } else { 718 static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture; 719 } 720 return res; 721} 722 723sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const { 724 sp<GraphicBuffer> result; 725 const ssize_t activeBuffer = mActiveBuffer; 726 if (activeBuffer >= 0) { 727 BufferData const * const buffers = mBufferData; 728 Mutex::Autolock _l(mLock); 729 result = buffers[activeBuffer].buffer; 730 } 731 return result; 732} 733 734sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index) 735{ 736 BufferData* const buffers = mBufferData; 737 sp<GraphicBuffer> buffer; 738 Mutex::Autolock _l(mLock); 739 buffer = buffers[index].buffer; 740 buffers[index].buffer = 0; 741 return buffer; 742} 743 744status_t Layer::BufferManager::attachBuffer(size_t index, 745 const sp<GraphicBuffer>& buffer) 746{ 747 BufferData* const buffers = mBufferData; 748 Mutex::Autolock _l(mLock); 749 buffers[index].buffer = buffer; 750 buffers[index].texture.dirty = true; 751 return NO_ERROR; 752} 753 754status_t Layer::BufferManager::destroy(EGLDisplay dpy) 755{ 756 BufferData* const buffers = mBufferData; 757 size_t num; 758 { // scope for the lock 759 Mutex::Autolock _l(mLock); 760 num = mNumBuffers; 761 for (size_t i=0 ; i<num ; i++) { 762 buffers[i].buffer = 0; 763 } 764 } 765 for (size_t i=0 ; i<num ; i++) { 766 destroyTexture(&buffers[i].texture, dpy); 767 } 768 destroyTexture(&mFailoverTexture, dpy); 769 return NO_ERROR; 770} 771 772status_t Layer::BufferManager::initEglImage(EGLDisplay dpy, 773 const sp<GraphicBuffer>& buffer) 774{ 775 status_t err = NO_INIT; 776 ssize_t index = mActiveBuffer; 777 if (index >= 0) { 778 if (!mFailover) { 779 Image& texture(mBufferData[index].texture); 780 err = mTextureManager.initEglImage(&texture, dpy, buffer); 781 // if EGLImage fails, we switch to regular texture mode, and we 782 // free all resources associated with using EGLImages. 783 if (err == NO_ERROR) { 784 mFailover = false; 785 destroyTexture(&mFailoverTexture, dpy); 786 } else { 787 mFailover = true; 788 const size_t num = mNumBuffers; 789 for (size_t i=0 ; i<num ; i++) { 790 destroyTexture(&mBufferData[i].texture, dpy); 791 } 792 } 793 } else { 794 // we failed once, don't try again 795 err = BAD_VALUE; 796 } 797 } 798 return err; 799} 800 801status_t Layer::BufferManager::loadTexture( 802 const Region& dirty, const GGLSurface& t) 803{ 804 return mTextureManager.loadTexture(&mFailoverTexture, dirty, t); 805} 806 807status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy) 808{ 809 if (tex->name != -1U) { 810 glDeleteTextures(1, &tex->name); 811 tex->name = -1U; 812 } 813 if (tex->image != EGL_NO_IMAGE_KHR) { 814 eglDestroyImageKHR(dpy, tex->image); 815 tex->image = EGL_NO_IMAGE_KHR; 816 } 817 return NO_ERROR; 818} 819 820// --------------------------------------------------------------------------- 821 822Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, 823 const sp<Layer>& owner) 824 : Surface(flinger, owner->getIdentity(), owner) 825{ 826} 827 828Layer::SurfaceLayer::~SurfaceLayer() 829{ 830} 831 832sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, 833 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) 834{ 835 sp<GraphicBuffer> buffer; 836 sp<Layer> owner(getOwner()); 837 if (owner != 0) { 838 /* 839 * requestBuffer() cannot be called from the main thread 840 * as it could cause a dead-lock, since it may have to wait 841 * on conditions updated my the main thread. 842 */ 843 buffer = owner->requestBuffer(index, w, h, format, usage); 844 } 845 return buffer; 846} 847 848status_t Layer::SurfaceLayer::setBufferCount(int bufferCount) 849{ 850 status_t err = DEAD_OBJECT; 851 sp<Layer> owner(getOwner()); 852 if (owner != 0) { 853 /* 854 * setBufferCount() cannot be called from the main thread 855 * as it could cause a dead-lock, since it may have to wait 856 * on conditions updated my the main thread. 857 */ 858 err = owner->setBufferCount(bufferCount); 859 } 860 return err; 861} 862 863// --------------------------------------------------------------------------- 864 865 866}; // namespace android 867