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