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