Layer.cpp revision 9f8386e1118c10dd4927f62637ec7162569bdbdc
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 if (isSecure() && !hw->isSecure()) { 255 layer.setSkip(true); 256 } 257 258 const State& s(drawingState()); 259 layer.setPlaneAlpha(s.alpha); 260 261 /* 262 * Transformations are applied in this order: 263 * 1) buffer orientation/flip/mirror 264 * 2) state transformation (window manager) 265 * 3) layer orientation (screen orientation) 266 * (NOTE: the matrices are multiplied in reverse order) 267 */ 268 269 const Transform bufferOrientation(mCurrentTransform); 270 const Transform tr(hw->getTransform() * s.transform * bufferOrientation); 271 272 // this gives us only the "orientation" component of the transform 273 const uint32_t finalTransform = tr.getOrientation(); 274 275 // we can only handle simple transformation 276 if (finalTransform & Transform::ROT_INVALID) { 277 layer.setSkip(true); 278 } else { 279 layer.setTransform(finalTransform); 280 } 281 layer.setCrop(computeBufferCrop()); 282} 283 284void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 285 HWComposer::HWCLayerInterface& layer) { 286 LayerBaseClient::setPerFrameData(hw, layer); 287 // NOTE: buffer can be NULL if the client never drew into this 288 // layer yet, or if we ran out of memory 289 layer.setBuffer(mActiveBuffer); 290} 291 292void Layer::setAcquireFence(const sp<const DisplayDevice>& hw, 293 HWComposer::HWCLayerInterface& layer) { 294 int fenceFd = -1; 295 296 // TODO: there is a possible optimization here: we only need to set the 297 // acquire fence the first time a new buffer is acquired on EACH display. 298 299 if (layer.getCompositionType() == HWC_OVERLAY) { 300 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 301 if (fence.get()) { 302 fenceFd = fence->dup(); 303 if (fenceFd == -1) { 304 ALOGW("failed to dup layer fence, skipping sync: %d", errno); 305 } 306 } 307 } 308 layer.setAcquireFenceFd(fenceFd); 309} 310 311void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const 312{ 313 ATRACE_CALL(); 314 315 if (CC_UNLIKELY(mActiveBuffer == 0)) { 316 // the texture has not been created yet, this Layer has 317 // in fact never been drawn into. This happens frequently with 318 // SurfaceView because the WindowManager can't know when the client 319 // has drawn the first time. 320 321 // If there is nothing under us, we paint the screen in black, otherwise 322 // we just skip this update. 323 324 // figure out if there is something below us 325 Region under; 326 const SurfaceFlinger::LayerVector& drawingLayers( 327 mFlinger->mDrawingState.layersSortedByZ); 328 const size_t count = drawingLayers.size(); 329 for (size_t i=0 ; i<count ; ++i) { 330 const sp<LayerBase>& layer(drawingLayers[i]); 331 if (layer.get() == static_cast<LayerBase const*>(this)) 332 break; 333 under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 334 } 335 // if not everything below us is covered, we plug the holes! 336 Region holes(clip.subtract(under)); 337 if (!holes.isEmpty()) { 338 clearWithOpenGL(hw, holes, 0, 0, 0, 1); 339 } 340 return; 341 } 342 343 // Bind the current buffer to the GL texture, and wait for it to be 344 // ready for us to draw into. 345 status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 346 if (err != NO_ERROR) { 347 ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 348 // Go ahead and draw the buffer anyway; no matter what we do the screen 349 // is probably going to have something visibly wrong. 350 } 351 352 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 353 354 if (!blackOutLayer) { 355 // TODO: we could be more subtle with isFixedSize() 356 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 357 358 // Query the texture matrix given our current filtering mode. 359 float textureMatrix[16]; 360 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 361 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 362 363 // Set things up for texturing. 364 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 365 GLenum filter = GL_NEAREST; 366 if (useFiltering) { 367 filter = GL_LINEAR; 368 } 369 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 370 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 371 glMatrixMode(GL_TEXTURE); 372 glLoadMatrixf(textureMatrix); 373 glMatrixMode(GL_MODELVIEW); 374 glDisable(GL_TEXTURE_2D); 375 glEnable(GL_TEXTURE_EXTERNAL_OES); 376 } else { 377 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 378 glMatrixMode(GL_TEXTURE); 379 glLoadIdentity(); 380 glMatrixMode(GL_MODELVIEW); 381 glDisable(GL_TEXTURE_EXTERNAL_OES); 382 glEnable(GL_TEXTURE_2D); 383 } 384 385 drawWithOpenGL(hw, clip); 386 387 glDisable(GL_TEXTURE_EXTERNAL_OES); 388 glDisable(GL_TEXTURE_2D); 389} 390 391// As documented in libhardware header, formats in the range 392// 0x100 - 0x1FF are specific to the HAL implementation, and 393// are known to have no alpha channel 394// TODO: move definition for device-specific range into 395// hardware.h, instead of using hard-coded values here. 396#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 397 398bool Layer::getOpacityForFormat(uint32_t format) 399{ 400 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 401 return true; 402 } 403 PixelFormatInfo info; 404 status_t err = getPixelFormatInfo(PixelFormat(format), &info); 405 // in case of error (unknown format), we assume no blending 406 return (err || info.h_alpha <= info.l_alpha); 407} 408 409 410bool Layer::isOpaque() const 411{ 412 // if we don't have a buffer yet, we're translucent regardless of the 413 // layer's opaque flag. 414 if (mActiveBuffer == 0) { 415 return false; 416 } 417 418 // if the layer has the opaque flag, then we're always opaque, 419 // otherwise we use the current buffer's format. 420 return mOpaqueLayer || mCurrentOpacity; 421} 422 423bool Layer::isProtected() const 424{ 425 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 426 return (activeBuffer != 0) && 427 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 428} 429 430uint32_t Layer::doTransaction(uint32_t flags) 431{ 432 ATRACE_CALL(); 433 434 const Layer::State& front(drawingState()); 435 const Layer::State& temp(currentState()); 436 437 const bool sizeChanged = (temp.requested.w != front.requested.w) || 438 (temp.requested.h != front.requested.h); 439 440 if (sizeChanged) { 441 // the size changed, we need to ask our client to request a new buffer 442 ALOGD_IF(DEBUG_RESIZE, 443 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 444 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 445 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 446 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 447 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 448 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode, 449 temp.active.w, temp.active.h, 450 temp.active.crop.left, 451 temp.active.crop.top, 452 temp.active.crop.right, 453 temp.active.crop.bottom, 454 temp.active.crop.getWidth(), 455 temp.active.crop.getHeight(), 456 temp.requested.w, temp.requested.h, 457 temp.requested.crop.left, 458 temp.requested.crop.top, 459 temp.requested.crop.right, 460 temp.requested.crop.bottom, 461 temp.requested.crop.getWidth(), 462 temp.requested.crop.getHeight(), 463 front.active.w, front.active.h, 464 front.active.crop.left, 465 front.active.crop.top, 466 front.active.crop.right, 467 front.active.crop.bottom, 468 front.active.crop.getWidth(), 469 front.active.crop.getHeight(), 470 front.requested.w, front.requested.h, 471 front.requested.crop.left, 472 front.requested.crop.top, 473 front.requested.crop.right, 474 front.requested.crop.bottom, 475 front.requested.crop.getWidth(), 476 front.requested.crop.getHeight()); 477 478 // record the new size, form this point on, when the client request 479 // a buffer, it'll get the new size. 480 mSurfaceFlingerConsumer->setDefaultBufferSize( 481 temp.requested.w, temp.requested.h); 482 } 483 484 if (!isFixedSize()) { 485 486 const bool resizePending = (temp.requested.w != temp.active.w) || 487 (temp.requested.h != temp.active.h); 488 489 if (resizePending) { 490 // don't let LayerBase::doTransaction update the drawing state 491 // if we have a pending resize, unless we are in fixed-size mode. 492 // the drawing state will be updated only once we receive a buffer 493 // with the correct size. 494 // 495 // in particular, we want to make sure the clip (which is part 496 // of the geometry state) is latched together with the size but is 497 // latched immediately when no resizing is involved. 498 499 flags |= eDontUpdateGeometryState; 500 } 501 } 502 503 return LayerBase::doTransaction(flags); 504} 505 506bool Layer::isFixedSize() const { 507 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 508} 509 510bool Layer::isCropped() const { 511 return !mCurrentCrop.isEmpty(); 512} 513 514// ---------------------------------------------------------------------------- 515// pageflip handling... 516// ---------------------------------------------------------------------------- 517 518bool Layer::onPreComposition() { 519 mRefreshPending = false; 520 return mQueuedFrames > 0; 521} 522 523void Layer::onPostComposition() { 524 if (mFrameLatencyNeeded) { 525 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 526 mFrameTracker.setDesiredPresentTime(desiredPresentTime); 527 528 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 529 if (frameReadyFence != NULL) { 530 mFrameTracker.setFrameReadyFence(frameReadyFence); 531 } else { 532 // There was no fence for this frame, so assume that it was ready 533 // to be presented at the desired present time. 534 mFrameTracker.setFrameReadyTime(desiredPresentTime); 535 } 536 537 const HWComposer& hwc = mFlinger->getHwComposer(); 538 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 539 // XXX: Temporarily don't use the present fence from HWC to work 540 // around a driver bug. 541 presentFence.clear(); 542 if (presentFence != NULL) { 543 mFrameTracker.setActualPresentFence(presentFence); 544 } else { 545 // The HWC doesn't support present fences, so use the refresh 546 // timestamp instead. 547 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 548 mFrameTracker.setActualPresentTime(presentTime); 549 } 550 551 mFrameTracker.advanceFrame(); 552 mFrameLatencyNeeded = false; 553 } 554} 555 556bool Layer::isVisible() const { 557 return LayerBaseClient::isVisible() && (mActiveBuffer != NULL); 558} 559 560Region Layer::latchBuffer(bool& recomputeVisibleRegions) 561{ 562 ATRACE_CALL(); 563 564 Region outDirtyRegion; 565 if (mQueuedFrames > 0) { 566 567 // if we've already called updateTexImage() without going through 568 // a composition step, we have to skip this layer at this point 569 // because we cannot call updateTeximage() without a corresponding 570 // compositionComplete() call. 571 // we'll trigger an update in onPreComposition(). 572 if (mRefreshPending) { 573 return outDirtyRegion; 574 } 575 576 // Capture the old state of the layer for comparisons later 577 const bool oldOpacity = isOpaque(); 578 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 579 580 // signal another event if we have more frames pending 581 if (android_atomic_dec(&mQueuedFrames) > 1) { 582 mFlinger->signalLayerUpdate(); 583 } 584 585 struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 586 Layer::State& front; 587 Layer::State& current; 588 bool& recomputeVisibleRegions; 589 Reject(Layer::State& front, Layer::State& current, 590 bool& recomputeVisibleRegions) 591 : front(front), current(current), 592 recomputeVisibleRegions(recomputeVisibleRegions) { 593 } 594 595 virtual bool reject(const sp<GraphicBuffer>& buf, 596 const BufferQueue::BufferItem& item) { 597 if (buf == NULL) { 598 return false; 599 } 600 601 uint32_t bufWidth = buf->getWidth(); 602 uint32_t bufHeight = buf->getHeight(); 603 604 // check that we received a buffer of the right size 605 // (Take the buffer's orientation into account) 606 if (item.mTransform & Transform::ROT_90) { 607 swap(bufWidth, bufHeight); 608 } 609 610 611 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 612 if (front.active != front.requested) { 613 614 if (isFixedSize || 615 (bufWidth == front.requested.w && 616 bufHeight == front.requested.h)) 617 { 618 // Here we pretend the transaction happened by updating the 619 // current and drawing states. Drawing state is only accessed 620 // in this thread, no need to have it locked 621 front.active = front.requested; 622 623 // We also need to update the current state so that 624 // we don't end-up overwriting the drawing state with 625 // this stale current state during the next transaction 626 // 627 // NOTE: We don't need to hold the transaction lock here 628 // because State::active is only accessed from this thread. 629 current.active = front.active; 630 631 // recompute visible region 632 recomputeVisibleRegions = true; 633 } 634 635 ALOGD_IF(DEBUG_RESIZE, 636 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 637 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 638 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 639 bufWidth, bufHeight, item.mTransform, item.mScalingMode, 640 front.active.w, front.active.h, 641 front.active.crop.left, 642 front.active.crop.top, 643 front.active.crop.right, 644 front.active.crop.bottom, 645 front.active.crop.getWidth(), 646 front.active.crop.getHeight(), 647 front.requested.w, front.requested.h, 648 front.requested.crop.left, 649 front.requested.crop.top, 650 front.requested.crop.right, 651 front.requested.crop.bottom, 652 front.requested.crop.getWidth(), 653 front.requested.crop.getHeight()); 654 } 655 656 if (!isFixedSize) { 657 if (front.active.w != bufWidth || 658 front.active.h != bufHeight) { 659 // reject this buffer 660 return true; 661 } 662 } 663 return false; 664 } 665 }; 666 667 668 Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 669 670 if (mSurfaceFlingerConsumer->updateTexImage(&r) != NO_ERROR) { 671 // something happened! 672 recomputeVisibleRegions = true; 673 return outDirtyRegion; 674 } 675 676 // update the active buffer 677 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 678 if (mActiveBuffer == NULL) { 679 // this can only happen if the very first buffer was rejected. 680 return outDirtyRegion; 681 } 682 683 mRefreshPending = true; 684 mFrameLatencyNeeded = true; 685 if (oldActiveBuffer == NULL) { 686 // the first time we receive a buffer, we need to trigger a 687 // geometry invalidation. 688 recomputeVisibleRegions = true; 689 } 690 691 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 692 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 693 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 694 if ((crop != mCurrentCrop) || 695 (transform != mCurrentTransform) || 696 (scalingMode != mCurrentScalingMode)) 697 { 698 mCurrentCrop = crop; 699 mCurrentTransform = transform; 700 mCurrentScalingMode = scalingMode; 701 recomputeVisibleRegions = true; 702 } 703 704 if (oldActiveBuffer != NULL) { 705 uint32_t bufWidth = mActiveBuffer->getWidth(); 706 uint32_t bufHeight = mActiveBuffer->getHeight(); 707 if (bufWidth != uint32_t(oldActiveBuffer->width) || 708 bufHeight != uint32_t(oldActiveBuffer->height)) { 709 recomputeVisibleRegions = true; 710 } 711 } 712 713 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 714 if (oldOpacity != isOpaque()) { 715 recomputeVisibleRegions = true; 716 } 717 718 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 719 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 720 721 // FIXME: postedRegion should be dirty & bounds 722 const Layer::State& front(drawingState()); 723 Region dirtyRegion(Rect(front.active.w, front.active.h)); 724 725 // transform the dirty region to window-manager space 726 outDirtyRegion = (front.transform.transform(dirtyRegion)); 727 } 728 return outDirtyRegion; 729} 730 731void Layer::dump(String8& result, char* buffer, size_t SIZE) const 732{ 733 LayerBaseClient::dump(result, buffer, SIZE); 734 735 sp<const GraphicBuffer> buf0(mActiveBuffer); 736 uint32_t w0=0, h0=0, s0=0, f0=0; 737 if (buf0 != 0) { 738 w0 = buf0->getWidth(); 739 h0 = buf0->getHeight(); 740 s0 = buf0->getStride(); 741 f0 = buf0->format; 742 } 743 snprintf(buffer, SIZE, 744 " " 745 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 746 " queued-frames=%d, mRefreshPending=%d\n", 747 mFormat, w0, h0, s0,f0, 748 mQueuedFrames, mRefreshPending); 749 750 result.append(buffer); 751 752 if (mSurfaceFlingerConsumer != 0) { 753 mSurfaceFlingerConsumer->dump(result, " ", buffer, SIZE); 754 } 755} 756 757void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 758{ 759 LayerBaseClient::dumpStats(result, buffer, SIZE); 760 const nsecs_t period = 761 mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 762 result.appendFormat("%lld\n", period); 763 mFrameTracker.dump(result); 764} 765 766void Layer::clearStats() 767{ 768 LayerBaseClient::clearStats(); 769 mFrameTracker.clear(); 770} 771 772uint32_t Layer::getEffectiveUsage(uint32_t usage) const 773{ 774 // TODO: should we do something special if mSecure is set? 775 if (mProtectedByApp) { 776 // need a hardware-protected path to external video sink 777 usage |= GraphicBuffer::USAGE_PROTECTED; 778 } 779 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 780 return usage; 781} 782 783void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 784 uint32_t orientation = 0; 785 if (!mFlinger->mDebugDisableTransformHint) { 786 // The transform hint is used to improve performance, but we can 787 // only have a single transform hint, it cannot 788 // apply to all displays. 789 const Transform& planeTransform(hw->getTransform()); 790 orientation = planeTransform.getOrientation(); 791 if (orientation & Transform::ROT_INVALID) { 792 orientation = 0; 793 } 794 } 795 mSurfaceFlingerConsumer->setTransformHint(orientation); 796} 797 798// --------------------------------------------------------------------------- 799 800 801}; // namespace android 802