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