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