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