Layer.cpp revision 3e8b853d67c737abdb363f9c978e7d83eac4d888
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(HWComposer::HWCLayerInterface& layer) 263{ 264 LayerBaseClient::setGeometry(layer); 265 266 // enable this layer 267 layer.setSkip(false); 268 269 // we can't do alpha-fade with the hwc HAL 270 const State& s(drawingState()); 271 if (s.alpha < 0xFF) { 272 layer.setSkip(true); 273 } 274 275 /* 276 * Transformations are applied in this order: 277 * 1) buffer orientation/flip/mirror 278 * 2) state transformation (window manager) 279 * 3) layer orientation (screen orientation) 280 * mTransform is already the composition of (2) and (3) 281 * (NOTE: the matrices are multiplied in reverse order) 282 */ 283 284 const Transform bufferOrientation(mCurrentTransform); 285 const Transform tr(mTransform * bufferOrientation); 286 287 // this gives us only the "orientation" component of the transform 288 const uint32_t finalTransform = tr.getOrientation(); 289 290 // we can only handle simple transformation 291 if (finalTransform & Transform::ROT_INVALID) { 292 layer.setSkip(true); 293 } else { 294 layer.setTransform(finalTransform); 295 } 296 layer.setCrop(computeBufferCrop()); 297} 298 299void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) { 300 const sp<GraphicBuffer>& buffer(mActiveBuffer); 301 // NOTE: buffer can be NULL if the client never drew into this 302 // layer yet, or if we ran out of memory 303 layer.setBuffer(buffer); 304} 305 306void Layer::onDraw(const Region& clip) const 307{ 308 ATRACE_CALL(); 309 310 if (CC_UNLIKELY(mActiveBuffer == 0)) { 311 // the texture has not been created yet, this Layer has 312 // in fact never been drawn into. This happens frequently with 313 // SurfaceView because the WindowManager can't know when the client 314 // has drawn the first time. 315 316 // If there is nothing under us, we paint the screen in black, otherwise 317 // we just skip this update. 318 319 // figure out if there is something below us 320 Region under; 321 const SurfaceFlinger::LayerVector& drawingLayers( 322 mFlinger->mDrawingState.layersSortedByZ); 323 const size_t count = drawingLayers.size(); 324 for (size_t i=0 ; i<count ; ++i) { 325 const sp<LayerBase>& layer(drawingLayers[i]); 326 if (layer.get() == static_cast<LayerBase const*>(this)) 327 break; 328 under.orSelf(layer->visibleRegionScreen); 329 } 330 // if not everything below us is covered, we plug the holes! 331 Region holes(clip.subtract(under)); 332 if (!holes.isEmpty()) { 333 clearWithOpenGL(holes, 0, 0, 0, 1); 334 } 335 return; 336 } 337 338 if (!isProtected()) { 339 // TODO: we could be more subtle with isFixedSize() 340 const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize(); 341 342 // Query the texture matrix given our current filtering mode. 343 float textureMatrix[16]; 344 mSurfaceTexture->setFilteringEnabled(useFiltering); 345 mSurfaceTexture->getTransformMatrix(textureMatrix); 346 347 // Set things up for texturing. 348 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 349 GLenum filter = GL_NEAREST; 350 if (useFiltering) { 351 filter = GL_LINEAR; 352 } 353 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 354 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 355 glMatrixMode(GL_TEXTURE); 356 glLoadMatrixf(textureMatrix); 357 glMatrixMode(GL_MODELVIEW); 358 glDisable(GL_TEXTURE_2D); 359 glEnable(GL_TEXTURE_EXTERNAL_OES); 360 } else { 361 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 362 glMatrixMode(GL_TEXTURE); 363 glLoadIdentity(); 364 glMatrixMode(GL_MODELVIEW); 365 glDisable(GL_TEXTURE_EXTERNAL_OES); 366 glEnable(GL_TEXTURE_2D); 367 } 368 369 drawWithOpenGL(clip); 370 371 glDisable(GL_TEXTURE_EXTERNAL_OES); 372 glDisable(GL_TEXTURE_2D); 373} 374 375// As documented in libhardware header, formats in the range 376// 0x100 - 0x1FF are specific to the HAL implementation, and 377// are known to have no alpha channel 378// TODO: move definition for device-specific range into 379// hardware.h, instead of using hard-coded values here. 380#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 381 382bool Layer::getOpacityForFormat(uint32_t format) 383{ 384 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 385 return true; 386 } 387 PixelFormatInfo info; 388 status_t err = getPixelFormatInfo(PixelFormat(format), &info); 389 // in case of error (unknown format), we assume no blending 390 return (err || info.h_alpha <= info.l_alpha); 391} 392 393 394bool Layer::isOpaque() const 395{ 396 // if we don't have a buffer yet, we're translucent regardless of the 397 // layer's opaque flag. 398 if (mActiveBuffer == 0) { 399 return false; 400 } 401 402 // if the layer has the opaque flag, then we're always opaque, 403 // otherwise we use the current buffer's format. 404 return mOpaqueLayer || mCurrentOpacity; 405} 406 407bool Layer::isProtected() const 408{ 409 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 410 return (activeBuffer != 0) && 411 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 412} 413 414uint32_t Layer::doTransaction(uint32_t flags) 415{ 416 ATRACE_CALL(); 417 418 const Layer::State& front(drawingState()); 419 const Layer::State& temp(currentState()); 420 421 const bool sizeChanged = (temp.requested.w != front.requested.w) || 422 (temp.requested.h != front.requested.h); 423 424 if (sizeChanged) { 425 // the size changed, we need to ask our client to request a new buffer 426 ALOGD_IF(DEBUG_RESIZE, 427 "doTransaction: geometry (layer=%p), scalingMode=%d\n" 428 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 429 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 430 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 431 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 432 this, mCurrentScalingMode, 433 temp.active.w, temp.active.h, 434 temp.active.crop.left, 435 temp.active.crop.top, 436 temp.active.crop.right, 437 temp.active.crop.bottom, 438 temp.active.crop.getWidth(), 439 temp.active.crop.getHeight(), 440 temp.requested.w, temp.requested.h, 441 temp.requested.crop.left, 442 temp.requested.crop.top, 443 temp.requested.crop.right, 444 temp.requested.crop.bottom, 445 temp.requested.crop.getWidth(), 446 temp.requested.crop.getHeight(), 447 front.active.w, front.active.h, 448 front.active.crop.left, 449 front.active.crop.top, 450 front.active.crop.right, 451 front.active.crop.bottom, 452 front.active.crop.getWidth(), 453 front.active.crop.getHeight(), 454 front.requested.w, front.requested.h, 455 front.requested.crop.left, 456 front.requested.crop.top, 457 front.requested.crop.right, 458 front.requested.crop.bottom, 459 front.requested.crop.getWidth(), 460 front.requested.crop.getHeight()); 461 462 // record the new size, form this point on, when the client request 463 // a buffer, it'll get the new size. 464 mSurfaceTexture->setDefaultBufferSize( 465 temp.requested.w, temp.requested.h); 466 } 467 468 if (!isFixedSize()) { 469 470 const bool resizePending = (temp.requested.w != temp.active.w) || 471 (temp.requested.h != temp.active.h); 472 473 if (resizePending) { 474 // don't let LayerBase::doTransaction update the drawing state 475 // if we have a pending resize, unless we are in fixed-size mode. 476 // the drawing state will be updated only once we receive a buffer 477 // with the correct size. 478 // 479 // in particular, we want to make sure the clip (which is part 480 // of the geometry state) is latched together with the size but is 481 // latched immediately when no resizing is involved. 482 483 flags |= eDontUpdateGeometryState; 484 } 485 } 486 487 return LayerBase::doTransaction(flags); 488} 489 490bool Layer::isFixedSize() const { 491 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 492} 493 494bool Layer::isCropped() const { 495 return !mCurrentCrop.isEmpty(); 496} 497 498// ---------------------------------------------------------------------------- 499// pageflip handling... 500// ---------------------------------------------------------------------------- 501 502bool Layer::onPreComposition() { 503 mRefreshPending = false; 504 return mQueuedFrames > 0; 505} 506 507void Layer::lockPageFlip(bool& recomputeVisibleRegions) 508{ 509 ATRACE_CALL(); 510 511 if (mQueuedFrames > 0) { 512 513 // if we've already called updateTexImage() without going through 514 // a composition step, we have to skip this layer at this point 515 // because we cannot call updateTeximage() without a corresponding 516 // compositionComplete() call. 517 // we'll trigger an update in onPreComposition(). 518 if (mRefreshPending) { 519 mPostedDirtyRegion.clear(); 520 return; 521 } 522 523 // Capture the old state of the layer for comparisons later 524 const bool oldOpacity = isOpaque(); 525 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 526 527 // signal another event if we have more frames pending 528 if (android_atomic_dec(&mQueuedFrames) > 1) { 529 mFlinger->signalLayerUpdate(); 530 } 531 532 struct Reject : public SurfaceTexture::BufferRejecter { 533 Layer::State& front; 534 Layer::State& current; 535 bool& recomputeVisibleRegions; 536 Reject(Layer::State& front, Layer::State& current, 537 bool& recomputeVisibleRegions) 538 : front(front), current(current), 539 recomputeVisibleRegions(recomputeVisibleRegions) { 540 } 541 542 virtual bool reject(const sp<GraphicBuffer>& buf, 543 const BufferQueue::BufferItem& item) { 544 if (buf == NULL) { 545 return false; 546 } 547 548 uint32_t bufWidth = buf->getWidth(); 549 uint32_t bufHeight = buf->getHeight(); 550 551 // check that we received a buffer of the right size 552 // (Take the buffer's orientation into account) 553 if (item.mTransform & Transform::ROT_90) { 554 swap(bufWidth, bufHeight); 555 } 556 557 558 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 559 if (front.active != front.requested) { 560 561 if (isFixedSize || 562 (bufWidth == front.requested.w && 563 bufHeight == front.requested.h)) 564 { 565 // Here we pretend the transaction happened by updating the 566 // current and drawing states. Drawing state is only accessed 567 // in this thread, no need to have it locked 568 front.active = front.requested; 569 570 // We also need to update the current state so that 571 // we don't end-up overwriting the drawing state with 572 // this stale current state during the next transaction 573 // 574 // NOTE: We don't need to hold the transaction lock here 575 // because State::active is only accessed from this thread. 576 current.active = front.active; 577 578 // recompute visible region 579 recomputeVisibleRegions = true; 580 } 581 582 ALOGD_IF(DEBUG_RESIZE, 583 "lockPageFlip: (layer=%p), buffer (%ux%u, tr=%02x), scalingMode=%d\n" 584 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 585 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 586 this, bufWidth, bufHeight, item.mTransform, item.mScalingMode, 587 front.active.w, front.active.h, 588 front.active.crop.left, 589 front.active.crop.top, 590 front.active.crop.right, 591 front.active.crop.bottom, 592 front.active.crop.getWidth(), 593 front.active.crop.getHeight(), 594 front.requested.w, front.requested.h, 595 front.requested.crop.left, 596 front.requested.crop.top, 597 front.requested.crop.right, 598 front.requested.crop.bottom, 599 front.requested.crop.getWidth(), 600 front.requested.crop.getHeight()); 601 } 602 603 if (!isFixedSize) { 604 if (front.active.w != bufWidth || 605 front.active.h != bufHeight) { 606 // reject this buffer 607 return true; 608 } 609 } 610 return false; 611 } 612 }; 613 614 615 Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 616 617 if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) { 618 // something happened! 619 recomputeVisibleRegions = true; 620 return; 621 } 622 623 // update the active buffer 624 mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 625 if (mActiveBuffer == NULL) { 626 // this can only happen if the very first buffer was rejected. 627 return; 628 } 629 630 mRefreshPending = true; 631 mFrameLatencyNeeded = true; 632 if (oldActiveBuffer == NULL) { 633 // the first time we receive a buffer, we need to trigger a 634 // geometry invalidation. 635 mFlinger->invalidateHwcGeometry(); 636 } 637 638 Rect crop(mSurfaceTexture->getCurrentCrop()); 639 const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 640 const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); 641 if ((crop != mCurrentCrop) || 642 (transform != mCurrentTransform) || 643 (scalingMode != mCurrentScalingMode)) 644 { 645 mCurrentCrop = crop; 646 mCurrentTransform = transform; 647 mCurrentScalingMode = scalingMode; 648 mFlinger->invalidateHwcGeometry(); 649 } 650 651 if (oldActiveBuffer != NULL) { 652 uint32_t bufWidth = mActiveBuffer->getWidth(); 653 uint32_t bufHeight = mActiveBuffer->getHeight(); 654 if (bufWidth != uint32_t(oldActiveBuffer->width) || 655 bufHeight != uint32_t(oldActiveBuffer->height)) { 656 mFlinger->invalidateHwcGeometry(); 657 } 658 } 659 660 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 661 if (oldOpacity != isOpaque()) { 662 recomputeVisibleRegions = true; 663 } 664 665 // FIXME: mPostedDirtyRegion = dirty & bounds 666 const Layer::State& front(drawingState()); 667 mPostedDirtyRegion.set(front.active.w, front.active.h); 668 669 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 670 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 671 } 672} 673 674void Layer::unlockPageFlip( 675 const Transform& planeTransform, Region& outDirtyRegion) 676{ 677 ATRACE_CALL(); 678 679 Region postedRegion(mPostedDirtyRegion); 680 if (!postedRegion.isEmpty()) { 681 mPostedDirtyRegion.clear(); 682 if (!visibleRegionScreen.isEmpty()) { 683 // The dirty region is given in the layer's coordinate space 684 // transform the dirty region by the surface's transformation 685 // and the global transformation. 686 const Layer::State& s(drawingState()); 687 const Transform tr(planeTransform * s.transform); 688 postedRegion = tr.transform(postedRegion); 689 690 // At this point, the dirty region is in screen space. 691 // Make sure it's constrained by the visible region (which 692 // is in screen space as well). 693 postedRegion.andSelf(visibleRegionScreen); 694 outDirtyRegion.orSelf(postedRegion); 695 } 696 } 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 DisplayHardware& hw(graphicPlane(0).displayHardware()); 730 const nsecs_t period = hw.getRefreshPeriod(); 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 orientation = getPlaneOrientation(); 766 if (orientation & Transform::ROT_INVALID) { 767 orientation = 0; 768 } 769 } 770 return orientation; 771} 772 773// --------------------------------------------------------------------------- 774 775 776}; // namespace android 777