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