Layer.cpp revision b79f61d41ef053bee1087ec612896c59f95f9686
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#define ATRACE_TAG ATRACE_TAG_GRAPHICS 18 19#include <stdlib.h> 20#include <stdint.h> 21#include <sys/types.h> 22 23#include <cutils/compiler.h> 24#include <cutils/native_handle.h> 25#include <cutils/properties.h> 26 27#include <utils/Errors.h> 28#include <utils/Log.h> 29#include <utils/StopWatch.h> 30#include <utils/Trace.h> 31 32#include <ui/GraphicBuffer.h> 33#include <ui/PixelFormat.h> 34 35#include <gui/Surface.h> 36 37#include "clz.h" 38#include "DisplayDevice.h" 39#include "GLExtensions.h" 40#include "Layer.h" 41#include "SurfaceFlinger.h" 42#include "SurfaceTextureLayer.h" 43 44#include "DisplayHardware/HWComposer.h" 45 46#define DEBUG_RESIZE 0 47 48namespace android { 49 50// --------------------------------------------------------------------------- 51 52Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client) 53 : LayerBase(flinger, client), 54 mTextureName(-1U), 55 mQueuedFrames(0), 56 mCurrentTransform(0), 57 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 58 mCurrentOpacity(true), 59 mRefreshPending(false), 60 mFrameLatencyNeeded(false), 61 mFormat(PIXEL_FORMAT_NONE), 62 mGLExtensions(GLExtensions::getInstance()), 63 mOpaqueLayer(true), 64 mSecure(false), 65 mProtectedByApp(false) 66{ 67 mCurrentCrop.makeInvalid(); 68 glGenTextures(1, &mTextureName); 69} 70 71void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw, 72 HWComposer::HWCLayerInterface* layer) { 73 LayerBase::onLayerDisplayed(hw, layer); 74 if (layer) { 75 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd()); 76 } 77} 78 79void Layer::onFirstRef() 80{ 81 LayerBase::onFirstRef(); 82 83 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use 84 sp<BufferQueue> bq = new SurfaceTextureLayer(); 85 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true, 86 GL_TEXTURE_EXTERNAL_OES, false, bq); 87 88 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 89 mSurfaceFlingerConsumer->setFrameAvailableListener(this); 90 mSurfaceFlingerConsumer->setSynchronousMode(true); 91 92#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 93#warning "disabling triple buffering" 94 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); 95#else 96 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3); 97#endif 98 99 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 100 updateTransformHint(hw); 101} 102 103Layer::~Layer() 104{ 105 mFlinger->deleteTextureAsync(mTextureName); 106} 107 108void Layer::onFrameAvailable() { 109 android_atomic_inc(&mQueuedFrames); 110 mFlinger->signalLayerUpdate(); 111} 112 113// called with SurfaceFlinger::mStateLock as soon as the layer is entered 114// in the purgatory list 115void Layer::onRemoved() 116{ 117 mSurfaceFlingerConsumer->abandon(); 118} 119 120void Layer::setName(const String8& name) { 121 LayerBase::setName(name); 122 mSurfaceFlingerConsumer->setName(name); 123} 124 125sp<ISurface> Layer::createSurface() 126{ 127 /* 128 * This class provides an implementation of BnSurface (the "native" or 129 * "remote" side of the Binder IPC interface ISurface), and mixes in 130 * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for 131 * this layer when the BSurface is destroyed. 132 * 133 * The idea is to provide a handle to the Layer through ISurface that 134 * is cleaned up automatically when the last reference to the ISurface 135 * goes away. (The references will be held on the "proxy" side, while 136 * the Layer exists on the "native" side.) 137 * 138 * The Layer has a reference to an instance of SurfaceFlinger's variant 139 * of GLConsumer, which holds a reference to the BufferQueue. The 140 * getSurfaceTexture() call returns a Binder interface reference for 141 * the producer interface of the buffer queue associated with the Layer. 142 */ 143 class BSurface : public BnSurface, public LayerCleaner { 144 wp<const Layer> mOwner; 145 virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { 146 sp<IGraphicBufferProducer> res; 147 sp<const Layer> that( mOwner.promote() ); 148 if (that != NULL) { 149 res = that->mSurfaceFlingerConsumer->getBufferQueue(); 150 } 151 return res; 152 } 153 public: 154 BSurface(const sp<SurfaceFlinger>& flinger, 155 const sp<Layer>& layer) 156 : LayerCleaner(flinger, layer), mOwner(layer) { } 157 }; 158 sp<ISurface> sur(new BSurface(mFlinger, this)); 159 return sur; 160} 161 162wp<IBinder> Layer::getSurfaceTextureBinder() const 163{ 164 return mSurfaceFlingerConsumer->getBufferQueue()->asBinder(); 165} 166 167status_t Layer::setBuffers( uint32_t w, uint32_t h, 168 PixelFormat format, uint32_t flags) 169{ 170 // this surfaces pixel format 171 PixelFormatInfo info; 172 status_t err = getPixelFormatInfo(format, &info); 173 if (err) { 174 ALOGE("unsupported pixelformat %d", format); 175 return err; 176 } 177 178 uint32_t const maxSurfaceDims = min( 179 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 180 181 // never allow a surface larger than what our underlying GL implementation 182 // can handle. 183 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 184 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 185 return BAD_VALUE; 186 } 187 188 mFormat = format; 189 190 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 191 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 192 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); 193 mCurrentOpacity = getOpacityForFormat(format); 194 195 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); 196 mSurfaceFlingerConsumer->setDefaultBufferFormat(format); 197 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 198 199 return NO_ERROR; 200} 201 202Rect Layer::getContentCrop() const { 203 // this is the crop rectangle that applies to the buffer 204 // itself (as opposed to the window) 205 Rect crop; 206 if (!mCurrentCrop.isEmpty()) { 207 // if the buffer crop is defined, we use that 208 crop = mCurrentCrop; 209 } else if (mActiveBuffer != NULL) { 210 // otherwise we use the whole buffer 211 crop = mActiveBuffer->getBounds(); 212 } else { 213 // if we don't have a buffer yet, we use an empty/invalid crop 214 crop.makeInvalid(); 215 } 216 return crop; 217} 218 219uint32_t Layer::getContentTransform() const { 220 return mCurrentTransform; 221} 222 223void Layer::setGeometry( 224 const sp<const DisplayDevice>& hw, 225 HWComposer::HWCLayerInterface& layer) 226{ 227 LayerBase::setGeometry(hw, layer); 228 229 // enable this layer 230 layer.setSkip(false); 231 232 if (isSecure() && !hw->isSecure()) { 233 layer.setSkip(true); 234 } 235 236 const State& s(drawingState()); 237 layer.setPlaneAlpha(s.alpha); 238 239 /* 240 * Transformations are applied in this order: 241 * 1) buffer orientation/flip/mirror 242 * 2) state transformation (window manager) 243 * 3) layer orientation (screen orientation) 244 * (NOTE: the matrices are multiplied in reverse order) 245 */ 246 247 const Transform bufferOrientation(mCurrentTransform); 248 const Transform tr(hw->getTransform() * s.transform * bufferOrientation); 249 250 // this gives us only the "orientation" component of the transform 251 const uint32_t finalTransform = tr.getOrientation(); 252 253 // we can only handle simple transformation 254 if (finalTransform & Transform::ROT_INVALID) { 255 layer.setSkip(true); 256 } else { 257 layer.setTransform(finalTransform); 258 } 259} 260 261void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 262 HWComposer::HWCLayerInterface& layer) { 263 LayerBase::setPerFrameData(hw, layer); 264 // NOTE: buffer can be NULL if the client never drew into this 265 // layer yet, or if we ran out of memory 266 layer.setBuffer(mActiveBuffer); 267} 268 269void Layer::setAcquireFence(const sp<const DisplayDevice>& hw, 270 HWComposer::HWCLayerInterface& layer) { 271 int fenceFd = -1; 272 273 // TODO: there is a possible optimization here: we only need to set the 274 // acquire fence the first time a new buffer is acquired on EACH display. 275 276 if (layer.getCompositionType() == HWC_OVERLAY) { 277 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 278 if (fence->isValid()) { 279 fenceFd = fence->dup(); 280 if (fenceFd == -1) { 281 ALOGW("failed to dup layer fence, skipping sync: %d", errno); 282 } 283 } 284 } 285 layer.setAcquireFenceFd(fenceFd); 286} 287 288void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const 289{ 290 ATRACE_CALL(); 291 292 if (CC_UNLIKELY(mActiveBuffer == 0)) { 293 // the texture has not been created yet, this Layer has 294 // in fact never been drawn into. This happens frequently with 295 // SurfaceView because the WindowManager can't know when the client 296 // has drawn the first time. 297 298 // If there is nothing under us, we paint the screen in black, otherwise 299 // we just skip this update. 300 301 // figure out if there is something below us 302 Region under; 303 const SurfaceFlinger::LayerVector& drawingLayers( 304 mFlinger->mDrawingState.layersSortedByZ); 305 const size_t count = drawingLayers.size(); 306 for (size_t i=0 ; i<count ; ++i) { 307 const sp<LayerBase>& layer(drawingLayers[i]); 308 if (layer.get() == static_cast<LayerBase const*>(this)) 309 break; 310 under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 311 } 312 // if not everything below us is covered, we plug the holes! 313 Region holes(clip.subtract(under)); 314 if (!holes.isEmpty()) { 315 clearWithOpenGL(hw, holes, 0, 0, 0, 1); 316 } 317 return; 318 } 319 320 // Bind the current buffer to the GL texture, and wait for it to be 321 // ready for us to draw into. 322 status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 323 if (err != NO_ERROR) { 324 ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 325 // Go ahead and draw the buffer anyway; no matter what we do the screen 326 // is probably going to have something visibly wrong. 327 } 328 329 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 330 331 if (!blackOutLayer) { 332 // TODO: we could be more subtle with isFixedSize() 333 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 334 335 // Query the texture matrix given our current filtering mode. 336 float textureMatrix[16]; 337 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 338 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 339 340 // Set things up for texturing. 341 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 342 GLenum filter = GL_NEAREST; 343 if (useFiltering) { 344 filter = GL_LINEAR; 345 } 346 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 347 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 348 glMatrixMode(GL_TEXTURE); 349 glLoadMatrixf(textureMatrix); 350 glMatrixMode(GL_MODELVIEW); 351 glDisable(GL_TEXTURE_2D); 352 glEnable(GL_TEXTURE_EXTERNAL_OES); 353 } else { 354 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 355 glMatrixMode(GL_TEXTURE); 356 glLoadIdentity(); 357 glMatrixMode(GL_MODELVIEW); 358 glDisable(GL_TEXTURE_EXTERNAL_OES); 359 glEnable(GL_TEXTURE_2D); 360 } 361 362 drawWithOpenGL(hw, clip); 363 364 glDisable(GL_TEXTURE_EXTERNAL_OES); 365 glDisable(GL_TEXTURE_2D); 366} 367 368// As documented in libhardware header, formats in the range 369// 0x100 - 0x1FF are specific to the HAL implementation, and 370// are known to have no alpha channel 371// TODO: move definition for device-specific range into 372// hardware.h, instead of using hard-coded values here. 373#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 374 375bool Layer::getOpacityForFormat(uint32_t format) 376{ 377 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 378 return true; 379 } 380 PixelFormatInfo info; 381 status_t err = getPixelFormatInfo(PixelFormat(format), &info); 382 // in case of error (unknown format), we assume no blending 383 return (err || info.h_alpha <= info.l_alpha); 384} 385 386 387bool Layer::isOpaque() const 388{ 389 // if we don't have a buffer yet, we're translucent regardless of the 390 // layer's opaque flag. 391 if (mActiveBuffer == 0) { 392 return false; 393 } 394 395 // if the layer has the opaque flag, then we're always opaque, 396 // otherwise we use the current buffer's format. 397 return mOpaqueLayer || mCurrentOpacity; 398} 399 400bool Layer::isProtected() const 401{ 402 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 403 return (activeBuffer != 0) && 404 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 405} 406 407uint32_t Layer::doTransaction(uint32_t flags) 408{ 409 ATRACE_CALL(); 410 411 const Layer::State& front(drawingState()); 412 const Layer::State& temp(currentState()); 413 414 const bool sizeChanged = (temp.requested.w != front.requested.w) || 415 (temp.requested.h != front.requested.h); 416 417 if (sizeChanged) { 418 // the size changed, we need to ask our client to request a new buffer 419 ALOGD_IF(DEBUG_RESIZE, 420 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 421 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 422 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 423 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 424 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 425 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode, 426 temp.active.w, temp.active.h, 427 temp.active.crop.left, 428 temp.active.crop.top, 429 temp.active.crop.right, 430 temp.active.crop.bottom, 431 temp.active.crop.getWidth(), 432 temp.active.crop.getHeight(), 433 temp.requested.w, temp.requested.h, 434 temp.requested.crop.left, 435 temp.requested.crop.top, 436 temp.requested.crop.right, 437 temp.requested.crop.bottom, 438 temp.requested.crop.getWidth(), 439 temp.requested.crop.getHeight(), 440 front.active.w, front.active.h, 441 front.active.crop.left, 442 front.active.crop.top, 443 front.active.crop.right, 444 front.active.crop.bottom, 445 front.active.crop.getWidth(), 446 front.active.crop.getHeight(), 447 front.requested.w, front.requested.h, 448 front.requested.crop.left, 449 front.requested.crop.top, 450 front.requested.crop.right, 451 front.requested.crop.bottom, 452 front.requested.crop.getWidth(), 453 front.requested.crop.getHeight()); 454 455 // record the new size, form this point on, when the client request 456 // a buffer, it'll get the new size. 457 mSurfaceFlingerConsumer->setDefaultBufferSize( 458 temp.requested.w, temp.requested.h); 459 } 460 461 if (!isFixedSize()) { 462 463 const bool resizePending = (temp.requested.w != temp.active.w) || 464 (temp.requested.h != temp.active.h); 465 466 if (resizePending) { 467 // don't let LayerBase::doTransaction update the drawing state 468 // if we have a pending resize, unless we are in fixed-size mode. 469 // the drawing state will be updated only once we receive a buffer 470 // with the correct size. 471 // 472 // in particular, we want to make sure the clip (which is part 473 // of the geometry state) is latched together with the size but is 474 // latched immediately when no resizing is involved. 475 476 flags |= eDontUpdateGeometryState; 477 } 478 } 479 480 return LayerBase::doTransaction(flags); 481} 482 483bool Layer::isFixedSize() const { 484 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 485} 486 487bool Layer::isCropped() const { 488 return !mCurrentCrop.isEmpty(); 489} 490 491// ---------------------------------------------------------------------------- 492// pageflip handling... 493// ---------------------------------------------------------------------------- 494 495bool Layer::onPreComposition() { 496 mRefreshPending = false; 497 return mQueuedFrames > 0; 498} 499 500void Layer::onPostComposition() { 501 if (mFrameLatencyNeeded) { 502 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 503 mFrameTracker.setDesiredPresentTime(desiredPresentTime); 504 505 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 506 if (frameReadyFence->isValid()) { 507 mFrameTracker.setFrameReadyFence(frameReadyFence); 508 } else { 509 // There was no fence for this frame, so assume that it was ready 510 // to be presented at the desired present time. 511 mFrameTracker.setFrameReadyTime(desiredPresentTime); 512 } 513 514 const HWComposer& hwc = mFlinger->getHwComposer(); 515 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 516 if (presentFence->isValid()) { 517 mFrameTracker.setActualPresentFence(presentFence); 518 } else { 519 // The HWC doesn't support present fences, so use the refresh 520 // timestamp instead. 521 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 522 mFrameTracker.setActualPresentTime(presentTime); 523 } 524 525 mFrameTracker.advanceFrame(); 526 mFrameLatencyNeeded = false; 527 } 528} 529 530bool Layer::isVisible() const { 531 return LayerBase::isVisible() && (mActiveBuffer != NULL); 532} 533 534Region Layer::latchBuffer(bool& recomputeVisibleRegions) 535{ 536 ATRACE_CALL(); 537 538 Region outDirtyRegion; 539 if (mQueuedFrames > 0) { 540 541 // if we've already called updateTexImage() without going through 542 // a composition step, we have to skip this layer at this point 543 // because we cannot call updateTeximage() without a corresponding 544 // compositionComplete() call. 545 // we'll trigger an update in onPreComposition(). 546 if (mRefreshPending) { 547 return outDirtyRegion; 548 } 549 550 // Capture the old state of the layer for comparisons later 551 const bool oldOpacity = isOpaque(); 552 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 553 554 // signal another event if we have more frames pending 555 if (android_atomic_dec(&mQueuedFrames) > 1) { 556 mFlinger->signalLayerUpdate(); 557 } 558 559 struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 560 Layer::State& front; 561 Layer::State& current; 562 bool& recomputeVisibleRegions; 563 Reject(Layer::State& front, Layer::State& current, 564 bool& recomputeVisibleRegions) 565 : front(front), current(current), 566 recomputeVisibleRegions(recomputeVisibleRegions) { 567 } 568 569 virtual bool reject(const sp<GraphicBuffer>& buf, 570 const BufferQueue::BufferItem& item) { 571 if (buf == NULL) { 572 return false; 573 } 574 575 uint32_t bufWidth = buf->getWidth(); 576 uint32_t bufHeight = buf->getHeight(); 577 578 // check that we received a buffer of the right size 579 // (Take the buffer's orientation into account) 580 if (item.mTransform & Transform::ROT_90) { 581 swap(bufWidth, bufHeight); 582 } 583 584 585 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 586 if (front.active != front.requested) { 587 588 if (isFixedSize || 589 (bufWidth == front.requested.w && 590 bufHeight == front.requested.h)) 591 { 592 // Here we pretend the transaction happened by updating the 593 // current and drawing states. Drawing state is only accessed 594 // in this thread, no need to have it locked 595 front.active = front.requested; 596 597 // We also need to update the current state so that 598 // we don't end-up overwriting the drawing state with 599 // this stale current state during the next transaction 600 // 601 // NOTE: We don't need to hold the transaction lock here 602 // because State::active is only accessed from this thread. 603 current.active = front.active; 604 605 // recompute visible region 606 recomputeVisibleRegions = true; 607 } 608 609 ALOGD_IF(DEBUG_RESIZE, 610 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 611 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 612 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 613 bufWidth, bufHeight, item.mTransform, item.mScalingMode, 614 front.active.w, front.active.h, 615 front.active.crop.left, 616 front.active.crop.top, 617 front.active.crop.right, 618 front.active.crop.bottom, 619 front.active.crop.getWidth(), 620 front.active.crop.getHeight(), 621 front.requested.w, front.requested.h, 622 front.requested.crop.left, 623 front.requested.crop.top, 624 front.requested.crop.right, 625 front.requested.crop.bottom, 626 front.requested.crop.getWidth(), 627 front.requested.crop.getHeight()); 628 } 629 630 if (!isFixedSize) { 631 if (front.active.w != bufWidth || 632 front.active.h != bufHeight) { 633 // reject this buffer 634 return true; 635 } 636 } 637 return false; 638 } 639 }; 640 641 642 Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 643 644 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) { 645 // something happened! 646 recomputeVisibleRegions = true; 647 return outDirtyRegion; 648 } 649 650 // update the active buffer 651 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 652 if (mActiveBuffer == NULL) { 653 // this can only happen if the very first buffer was rejected. 654 return outDirtyRegion; 655 } 656 657 mRefreshPending = true; 658 mFrameLatencyNeeded = true; 659 if (oldActiveBuffer == NULL) { 660 // the first time we receive a buffer, we need to trigger a 661 // geometry invalidation. 662 recomputeVisibleRegions = true; 663 } 664 665 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 666 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 667 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 668 if ((crop != mCurrentCrop) || 669 (transform != mCurrentTransform) || 670 (scalingMode != mCurrentScalingMode)) 671 { 672 mCurrentCrop = crop; 673 mCurrentTransform = transform; 674 mCurrentScalingMode = scalingMode; 675 recomputeVisibleRegions = true; 676 } 677 678 if (oldActiveBuffer != NULL) { 679 uint32_t bufWidth = mActiveBuffer->getWidth(); 680 uint32_t bufHeight = mActiveBuffer->getHeight(); 681 if (bufWidth != uint32_t(oldActiveBuffer->width) || 682 bufHeight != uint32_t(oldActiveBuffer->height)) { 683 recomputeVisibleRegions = true; 684 } 685 } 686 687 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 688 if (oldOpacity != isOpaque()) { 689 recomputeVisibleRegions = true; 690 } 691 692 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 693 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 694 695 // FIXME: postedRegion should be dirty & bounds 696 const Layer::State& front(drawingState()); 697 Region dirtyRegion(Rect(front.active.w, front.active.h)); 698 699 // transform the dirty region to window-manager space 700 outDirtyRegion = (front.transform.transform(dirtyRegion)); 701 } 702 return outDirtyRegion; 703} 704 705void Layer::dump(String8& result, char* buffer, size_t SIZE) const 706{ 707 LayerBase::dump(result, buffer, SIZE); 708 709 sp<const GraphicBuffer> buf0(mActiveBuffer); 710 uint32_t w0=0, h0=0, s0=0, f0=0; 711 if (buf0 != 0) { 712 w0 = buf0->getWidth(); 713 h0 = buf0->getHeight(); 714 s0 = buf0->getStride(); 715 f0 = buf0->format; 716 } 717 snprintf(buffer, SIZE, 718 " " 719 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 720 " queued-frames=%d, mRefreshPending=%d\n", 721 mFormat, w0, h0, s0,f0, 722 mQueuedFrames, mRefreshPending); 723 724 result.append(buffer); 725 726 if (mSurfaceFlingerConsumer != 0) { 727 mSurfaceFlingerConsumer->dump(result, " ", buffer, SIZE); 728 } 729} 730 731void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 732{ 733 LayerBase::dumpStats(result, buffer, SIZE); 734 mFrameTracker.dump(result); 735} 736 737void Layer::clearStats() 738{ 739 LayerBase::clearStats(); 740 mFrameTracker.clear(); 741} 742 743uint32_t Layer::getEffectiveUsage(uint32_t usage) const 744{ 745 // TODO: should we do something special if mSecure is set? 746 if (mProtectedByApp) { 747 // need a hardware-protected path to external video sink 748 usage |= GraphicBuffer::USAGE_PROTECTED; 749 } 750 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 751 return usage; 752} 753 754void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 755 uint32_t orientation = 0; 756 if (!mFlinger->mDebugDisableTransformHint) { 757 // The transform hint is used to improve performance, but we can 758 // only have a single transform hint, it cannot 759 // apply to all displays. 760 const Transform& planeTransform(hw->getTransform()); 761 orientation = planeTransform.getOrientation(); 762 if (orientation & Transform::ROT_INVALID) { 763 orientation = 0; 764 } 765 } 766 mSurfaceFlingerConsumer->setTransformHint(orientation); 767} 768 769// --------------------------------------------------------------------------- 770 771 772}; // namespace android 773