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