Layer.cpp revision df85c455c34a920d22a8e3f7459a1cc615efcd27
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 LOGE_IF(err || buffer->handle == 0, 351 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)", 352 this, index, w, h, strerror(-err)); 353 } else { 354 LOGD_IF(DEBUG_RESIZE, 355 "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p", 356 this, index, w, h, buffer->handle); 357 } 358 359 if (err == NO_ERROR && buffer->handle != 0) { 360 Mutex::Autolock _l(mLock); 361 mBufferManager.attachBuffer(index, buffer); 362 } 363 return buffer; 364} 365 366uint32_t Layer::getEffectiveUsage(uint32_t usage) const 367{ 368 /* 369 * buffers used for software rendering, but h/w composition 370 * are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE 371 * 372 * buffers used for h/w rendering and h/w composition 373 * are allocated with HW_RENDER | HW_TEXTURE 374 * 375 * buffers used with h/w rendering and either NPOT or no egl_image_ext 376 * are allocated with SW_READ_RARELY | HW_RENDER 377 * 378 */ 379 380 if (mSecure) { 381 // secure buffer, don't store it into the GPU 382 usage = GraphicBuffer::USAGE_SW_READ_OFTEN | 383 GraphicBuffer::USAGE_SW_WRITE_OFTEN; 384 } else { 385 // it's allowed to modify the usage flags here, but generally 386 // the requested flags should be honored. 387 // request EGLImage for all buffers 388 usage |= GraphicBuffer::USAGE_HW_TEXTURE; 389 } 390 return usage; 391} 392 393uint32_t Layer::doTransaction(uint32_t flags) 394{ 395 const Layer::State& front(drawingState()); 396 const Layer::State& temp(currentState()); 397 398 const bool sizeChanged = (front.requested_w != temp.requested_w) || 399 (front.requested_h != temp.requested_h); 400 401 if (sizeChanged) { 402 // the size changed, we need to ask our client to request a new buffer 403 LOGD_IF(DEBUG_RESIZE, 404 "resize (layer=%p), requested (%dx%d), drawing (%d,%d)", 405 this, 406 int(temp.requested_w), int(temp.requested_h), 407 int(front.requested_w), int(front.requested_h)); 408 409 if (!isFixedSize()) { 410 // we're being resized and there is a freeze display request, 411 // acquire a freeze lock, so that the screen stays put 412 // until we've redrawn at the new size; this is to avoid 413 // glitches upon orientation changes. 414 if (mFlinger->hasFreezeRequest()) { 415 // if the surface is hidden, don't try to acquire the 416 // freeze lock, since hidden surfaces may never redraw 417 if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 418 mFreezeLock = mFlinger->getFreezeLock(); 419 } 420 } 421 422 // this will make sure LayerBase::doTransaction doesn't update 423 // the drawing state's size 424 Layer::State& editDraw(mDrawingState); 425 editDraw.requested_w = temp.requested_w; 426 editDraw.requested_h = temp.requested_h; 427 428 // record the new size, form this point on, when the client request 429 // a buffer, it'll get the new size. 430 setBufferSize(temp.requested_w, temp.requested_h); 431 432 ClientRef::Access sharedClient(mUserClientRef); 433 SharedBufferServer* lcblk(sharedClient.get()); 434 if (lcblk) { 435 // all buffers need reallocation 436 lcblk->reallocateAll(); 437 } 438 } else { 439 // record the new size 440 setBufferSize(temp.requested_w, temp.requested_h); 441 } 442 } 443 444 if (temp.sequence != front.sequence) { 445 if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 446 // this surface is now hidden, so it shouldn't hold a freeze lock 447 // (it may never redraw, which is fine if it is hidden) 448 mFreezeLock.clear(); 449 } 450 } 451 452 return LayerBase::doTransaction(flags); 453} 454 455void Layer::setBufferSize(uint32_t w, uint32_t h) { 456 Mutex::Autolock _l(mLock); 457 mWidth = w; 458 mHeight = h; 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