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