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