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