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