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