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