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