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