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