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