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