Layer.cpp revision 46b6bce198c81ce9a4e0583e876d080ad48db003
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 // XXX: Temporarily don't use the fence from the SurfaceTexture to 515 // work around a driver bug. 516 frameReadyFence.clear(); 517 if (frameReadyFence != NULL) { 518 mFrameTracker.setFrameReadyFence(frameReadyFence); 519 } else { 520 // There was no fence for this frame, so assume that it was ready 521 // to be presented at the desired present time. 522 mFrameTracker.setFrameReadyTime(desiredPresentTime); 523 } 524 525 const HWComposer& hwc = mFlinger->getHwComposer(); 526 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 527 // XXX: Temporarily don't use the present fence from HWC to work 528 // around a driver bug. 529 presentFence.clear(); 530 if (presentFence != NULL) { 531 mFrameTracker.setActualPresentFence(presentFence); 532 } else { 533 // The HWC doesn't support present fences, so use the refresh 534 // timestamp instead. 535 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 536 mFrameTracker.setActualPresentTime(presentTime); 537 } 538 539 mFrameTracker.advanceFrame(); 540 mFrameLatencyNeeded = false; 541 } 542} 543 544bool Layer::isVisible() const { 545 return LayerBaseClient::isVisible() && (mActiveBuffer != NULL); 546} 547 548Region Layer::latchBuffer(bool& recomputeVisibleRegions) 549{ 550 ATRACE_CALL(); 551 552 Region outDirtyRegion; 553 if (mQueuedFrames > 0) { 554 555 // if we've already called updateTexImage() without going through 556 // a composition step, we have to skip this layer at this point 557 // because we cannot call updateTeximage() without a corresponding 558 // compositionComplete() call. 559 // we'll trigger an update in onPreComposition(). 560 if (mRefreshPending) { 561 return outDirtyRegion; 562 } 563 564 // Capture the old state of the layer for comparisons later 565 const bool oldOpacity = isOpaque(); 566 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 567 568 // signal another event if we have more frames pending 569 if (android_atomic_dec(&mQueuedFrames) > 1) { 570 mFlinger->signalLayerUpdate(); 571 } 572 573 struct Reject : public SurfaceTexture::BufferRejecter { 574 Layer::State& front; 575 Layer::State& current; 576 bool& recomputeVisibleRegions; 577 Reject(Layer::State& front, Layer::State& current, 578 bool& recomputeVisibleRegions) 579 : front(front), current(current), 580 recomputeVisibleRegions(recomputeVisibleRegions) { 581 } 582 583 virtual bool reject(const sp<GraphicBuffer>& buf, 584 const BufferQueue::BufferItem& item) { 585 if (buf == NULL) { 586 return false; 587 } 588 589 uint32_t bufWidth = buf->getWidth(); 590 uint32_t bufHeight = buf->getHeight(); 591 592 // check that we received a buffer of the right size 593 // (Take the buffer's orientation into account) 594 if (item.mTransform & Transform::ROT_90) { 595 swap(bufWidth, bufHeight); 596 } 597 598 599 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 600 if (front.active != front.requested) { 601 602 if (isFixedSize || 603 (bufWidth == front.requested.w && 604 bufHeight == front.requested.h)) 605 { 606 // Here we pretend the transaction happened by updating the 607 // current and drawing states. Drawing state is only accessed 608 // in this thread, no need to have it locked 609 front.active = front.requested; 610 611 // We also need to update the current state so that 612 // we don't end-up overwriting the drawing state with 613 // this stale current state during the next transaction 614 // 615 // NOTE: We don't need to hold the transaction lock here 616 // because State::active is only accessed from this thread. 617 current.active = front.active; 618 619 // recompute visible region 620 recomputeVisibleRegions = true; 621 } 622 623 ALOGD_IF(DEBUG_RESIZE, 624 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 625 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 626 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 627 bufWidth, bufHeight, item.mTransform, item.mScalingMode, 628 front.active.w, front.active.h, 629 front.active.crop.left, 630 front.active.crop.top, 631 front.active.crop.right, 632 front.active.crop.bottom, 633 front.active.crop.getWidth(), 634 front.active.crop.getHeight(), 635 front.requested.w, front.requested.h, 636 front.requested.crop.left, 637 front.requested.crop.top, 638 front.requested.crop.right, 639 front.requested.crop.bottom, 640 front.requested.crop.getWidth(), 641 front.requested.crop.getHeight()); 642 } 643 644 if (!isFixedSize) { 645 if (front.active.w != bufWidth || 646 front.active.h != bufHeight) { 647 // reject this buffer 648 return true; 649 } 650 } 651 return false; 652 } 653 }; 654 655 656 Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 657 658 if (mSurfaceTexture->updateTexImage(&r, true) < NO_ERROR) { 659 // something happened! 660 recomputeVisibleRegions = true; 661 return outDirtyRegion; 662 } 663 664 // update the active buffer 665 mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 666 if (mActiveBuffer == NULL) { 667 // this can only happen if the very first buffer was rejected. 668 return outDirtyRegion; 669 } 670 671 mRefreshPending = true; 672 mFrameLatencyNeeded = true; 673 if (oldActiveBuffer == NULL) { 674 // the first time we receive a buffer, we need to trigger a 675 // geometry invalidation. 676 recomputeVisibleRegions = true; 677 } 678 679 Rect crop(mSurfaceTexture->getCurrentCrop()); 680 const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 681 const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); 682 if ((crop != mCurrentCrop) || 683 (transform != mCurrentTransform) || 684 (scalingMode != mCurrentScalingMode)) 685 { 686 mCurrentCrop = crop; 687 mCurrentTransform = transform; 688 mCurrentScalingMode = scalingMode; 689 recomputeVisibleRegions = true; 690 } 691 692 if (oldActiveBuffer != NULL) { 693 uint32_t bufWidth = mActiveBuffer->getWidth(); 694 uint32_t bufHeight = mActiveBuffer->getHeight(); 695 if (bufWidth != uint32_t(oldActiveBuffer->width) || 696 bufHeight != uint32_t(oldActiveBuffer->height)) { 697 recomputeVisibleRegions = true; 698 } 699 } 700 701 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 702 if (oldOpacity != isOpaque()) { 703 recomputeVisibleRegions = true; 704 } 705 706 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 707 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 708 709 // FIXME: postedRegion should be dirty & bounds 710 const Layer::State& front(drawingState()); 711 Region dirtyRegion(Rect(front.active.w, front.active.h)); 712 713 // transform the dirty region to window-manager space 714 outDirtyRegion = (front.transform.transform(dirtyRegion)); 715 } 716 return outDirtyRegion; 717} 718 719void Layer::dump(String8& result, char* buffer, size_t SIZE) const 720{ 721 LayerBaseClient::dump(result, buffer, SIZE); 722 723 sp<const GraphicBuffer> buf0(mActiveBuffer); 724 uint32_t w0=0, h0=0, s0=0, f0=0; 725 if (buf0 != 0) { 726 w0 = buf0->getWidth(); 727 h0 = buf0->getHeight(); 728 s0 = buf0->getStride(); 729 f0 = buf0->format; 730 } 731 snprintf(buffer, SIZE, 732 " " 733 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 734 " queued-frames=%d, mRefreshPending=%d\n", 735 mFormat, w0, h0, s0,f0, 736 mQueuedFrames, mRefreshPending); 737 738 result.append(buffer); 739 740 if (mSurfaceTexture != 0) { 741 mSurfaceTexture->dump(result, " ", buffer, SIZE); 742 } 743} 744 745void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 746{ 747 LayerBaseClient::dumpStats(result, buffer, SIZE); 748 const nsecs_t period = 749 mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 750 result.appendFormat("%lld\n", period); 751 mFrameTracker.dump(result); 752} 753 754void Layer::clearStats() 755{ 756 LayerBaseClient::clearStats(); 757 mFrameTracker.clear(); 758} 759 760uint32_t Layer::getEffectiveUsage(uint32_t usage) const 761{ 762 // TODO: should we do something special if mSecure is set? 763 if (mProtectedByApp) { 764 // need a hardware-protected path to external video sink 765 usage |= GraphicBuffer::USAGE_PROTECTED; 766 } 767 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 768 return usage; 769} 770 771void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 772 uint32_t orientation = 0; 773 if (!mFlinger->mDebugDisableTransformHint) { 774 // The transform hint is used to improve performance, but we can 775 // only have a single transform hint, it cannot 776 // apply to all displays. 777 const Transform& planeTransform(hw->getTransform()); 778 orientation = planeTransform.getOrientation(); 779 if (orientation & Transform::ROT_INVALID) { 780 orientation = 0; 781 } 782 } 783 mSurfaceTexture->setTransformHint(orientation); 784} 785 786// --------------------------------------------------------------------------- 787 788 789}; // namespace android 790