Layer.cpp revision 1440963470cda68be762957e2efb7ecbe1570366
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/NativeHandle.h> 31#include <utils/StopWatch.h> 32#include <utils/Trace.h> 33 34#include <ui/GraphicBuffer.h> 35#include <ui/PixelFormat.h> 36 37#include <gui/Surface.h> 38 39#include "clz.h" 40#include "Colorizer.h" 41#include "DisplayDevice.h" 42#include "Layer.h" 43#include "MonitoredProducer.h" 44#include "SurfaceFlinger.h" 45 46#include "DisplayHardware/HWComposer.h" 47 48#include "RenderEngine/RenderEngine.h" 49 50#define DEBUG_RESIZE 0 51 52namespace android { 53 54// --------------------------------------------------------------------------- 55 56int32_t Layer::sSequence = 1; 57 58Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, 59 const String8& name, uint32_t w, uint32_t h, uint32_t flags) 60 : contentDirty(false), 61 sequence(uint32_t(android_atomic_inc(&sSequence))), 62 mFlinger(flinger), 63 mTextureName(-1U), 64 mPremultipliedAlpha(true), 65 mName("unnamed"), 66 mDebug(false), 67 mFormat(PIXEL_FORMAT_NONE), 68 mTransactionFlags(0), 69 mQueuedFrames(0), 70 mSidebandStreamChanged(false), 71 mCurrentTransform(0), 72 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 73 mCurrentOpacity(true), 74 mRefreshPending(false), 75 mFrameLatencyNeeded(false), 76 mFiltering(false), 77 mNeedsFiltering(false), 78 mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2), 79 mSecure(false), 80 mProtectedByApp(false), 81 mHasSurface(false), 82 mClientRef(client), 83 mPotentialCursor(false) 84{ 85 mCurrentCrop.makeInvalid(); 86 mFlinger->getRenderEngine().genTextures(1, &mTextureName); 87 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName); 88 89 uint32_t layerFlags = 0; 90 if (flags & ISurfaceComposerClient::eHidden) 91 layerFlags |= layer_state_t::eLayerHidden; 92 if (flags & ISurfaceComposerClient::eOpaque) 93 layerFlags |= layer_state_t::eLayerOpaque; 94 95 if (flags & ISurfaceComposerClient::eNonPremultiplied) 96 mPremultipliedAlpha = false; 97 98 mName = name; 99 100 mCurrentState.active.w = w; 101 mCurrentState.active.h = h; 102 mCurrentState.active.crop.makeInvalid(); 103 mCurrentState.z = 0; 104 mCurrentState.alpha = 0xFF; 105 mCurrentState.layerStack = 0; 106 mCurrentState.flags = layerFlags; 107 mCurrentState.sequence = 0; 108 mCurrentState.transform.set(0, 0); 109 mCurrentState.requested = mCurrentState.active; 110 111 // drawing state & current state are identical 112 mDrawingState = mCurrentState; 113 114 nsecs_t displayPeriod = 115 flinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 116 mFrameTracker.setDisplayRefreshPeriod(displayPeriod); 117} 118 119void Layer::onFirstRef() { 120 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use 121 sp<IGraphicBufferProducer> producer; 122 sp<IGraphicBufferConsumer> consumer; 123 BufferQueue::createBufferQueue(&producer, &consumer); 124 mProducer = new MonitoredProducer(producer, mFlinger); 125 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName); 126 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 127 mSurfaceFlingerConsumer->setContentsChangedListener(this); 128 mSurfaceFlingerConsumer->setName(mName); 129 130#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 131#warning "disabling triple buffering" 132 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2); 133#else 134 mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3); 135#endif 136 137 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 138 updateTransformHint(hw); 139} 140 141Layer::~Layer() { 142 sp<Client> c(mClientRef.promote()); 143 if (c != 0) { 144 c->detachLayer(this); 145 } 146 mFlinger->deleteTextureAsync(mTextureName); 147 mFrameTracker.logAndResetStats(mName); 148} 149 150// --------------------------------------------------------------------------- 151// callbacks 152// --------------------------------------------------------------------------- 153 154void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */, 155 HWComposer::HWCLayerInterface* layer) { 156 if (layer) { 157 layer->onDisplayed(); 158 mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFence()); 159 } 160} 161 162void Layer::onFrameAvailable() { 163 android_atomic_inc(&mQueuedFrames); 164 mFlinger->signalLayerUpdate(); 165} 166 167void Layer::onSidebandStreamChanged() { 168 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) { 169 // mSidebandStreamChanged was false 170 mFlinger->signalLayerUpdate(); 171 } 172} 173 174// called with SurfaceFlinger::mStateLock from the drawing thread after 175// the layer has been remove from the current state list (and just before 176// it's removed from the drawing state list) 177void Layer::onRemoved() { 178 mSurfaceFlingerConsumer->abandon(); 179} 180 181// --------------------------------------------------------------------------- 182// set-up 183// --------------------------------------------------------------------------- 184 185const String8& Layer::getName() const { 186 return mName; 187} 188 189status_t Layer::setBuffers( uint32_t w, uint32_t h, 190 PixelFormat format, uint32_t flags) 191{ 192 uint32_t const maxSurfaceDims = min( 193 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 194 195 // never allow a surface larger than what our underlying GL implementation 196 // can handle. 197 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 198 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 199 return BAD_VALUE; 200 } 201 202 mFormat = format; 203 204 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false; 205 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 206 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 207 mCurrentOpacity = getOpacityForFormat(format); 208 209 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h); 210 mSurfaceFlingerConsumer->setDefaultBufferFormat(format); 211 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0)); 212 213 return NO_ERROR; 214} 215 216sp<IBinder> Layer::getHandle() { 217 Mutex::Autolock _l(mLock); 218 219 LOG_ALWAYS_FATAL_IF(mHasSurface, 220 "Layer::getHandle() has already been called"); 221 222 mHasSurface = true; 223 224 /* 225 * The layer handle is just a BBinder object passed to the client 226 * (remote process) -- we don't keep any reference on our side such that 227 * the dtor is called when the remote side let go of its reference. 228 * 229 * LayerCleaner ensures that mFlinger->onLayerDestroyed() is called for 230 * this layer when the handle is destroyed. 231 */ 232 233 class Handle : public BBinder, public LayerCleaner { 234 wp<const Layer> mOwner; 235 public: 236 Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer) 237 : LayerCleaner(flinger, layer), mOwner(layer) { 238 } 239 }; 240 241 return new Handle(mFlinger, this); 242} 243 244sp<IGraphicBufferProducer> Layer::getProducer() const { 245 return mProducer; 246} 247 248// --------------------------------------------------------------------------- 249// h/w composer set-up 250// --------------------------------------------------------------------------- 251 252Rect Layer::getContentCrop() const { 253 // this is the crop rectangle that applies to the buffer 254 // itself (as opposed to the window) 255 Rect crop; 256 if (!mCurrentCrop.isEmpty()) { 257 // if the buffer crop is defined, we use that 258 crop = mCurrentCrop; 259 } else if (mActiveBuffer != NULL) { 260 // otherwise we use the whole buffer 261 crop = mActiveBuffer->getBounds(); 262 } else { 263 // if we don't have a buffer yet, we use an empty/invalid crop 264 crop.makeInvalid(); 265 } 266 return crop; 267} 268 269static Rect reduce(const Rect& win, const Region& exclude) { 270 if (CC_LIKELY(exclude.isEmpty())) { 271 return win; 272 } 273 if (exclude.isRect()) { 274 return win.reduce(exclude.getBounds()); 275 } 276 return Region(win).subtract(exclude).getBounds(); 277} 278 279Rect Layer::computeBounds() const { 280 const Layer::State& s(getDrawingState()); 281 Rect win(s.active.w, s.active.h); 282 if (!s.active.crop.isEmpty()) { 283 win.intersect(s.active.crop, &win); 284 } 285 // subtract the transparent region and snap to the bounds 286 return reduce(win, s.activeTransparentRegion); 287} 288 289FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const { 290 // the content crop is the area of the content that gets scaled to the 291 // layer's size. 292 FloatRect crop(getContentCrop()); 293 294 // the active.crop is the area of the window that gets cropped, but not 295 // scaled in any ways. 296 const State& s(getDrawingState()); 297 298 // apply the projection's clipping to the window crop in 299 // layerstack space, and convert-back to layer space. 300 // if there are no window scaling involved, this operation will map to full 301 // pixels in the buffer. 302 // FIXME: the 3 lines below can produce slightly incorrect clipping when we have 303 // a viewport clipping and a window transform. we should use floating point to fix this. 304 305 Rect activeCrop(s.active.w, s.active.h); 306 if (!s.active.crop.isEmpty()) { 307 activeCrop = s.active.crop; 308 } 309 310 activeCrop = s.transform.transform(activeCrop); 311 activeCrop.intersect(hw->getViewport(), &activeCrop); 312 activeCrop = s.transform.inverse().transform(activeCrop); 313 314 // paranoia: make sure the window-crop is constrained in the 315 // window's bounds 316 activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop); 317 318 // subtract the transparent region and snap to the bounds 319 activeCrop = reduce(activeCrop, s.activeTransparentRegion); 320 321 if (!activeCrop.isEmpty()) { 322 // Transform the window crop to match the buffer coordinate system, 323 // which means using the inverse of the current transform set on the 324 // SurfaceFlingerConsumer. 325 uint32_t invTransform = mCurrentTransform; 326 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 327 /* 328 * the code below applies the display's inverse transform to the buffer 329 */ 330 uint32_t invTransformOrient = hw->getOrientationTransform(); 331 // calculate the inverse transform 332 if (invTransformOrient & NATIVE_WINDOW_TRANSFORM_ROT_90) { 333 invTransformOrient ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 334 NATIVE_WINDOW_TRANSFORM_FLIP_H; 335 // If the transform has been rotated the axis of flip has been swapped 336 // so we need to swap which flip operations we are performing 337 bool is_h_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; 338 bool is_v_flipped = (invTransform & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; 339 if (is_h_flipped != is_v_flipped) { 340 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 341 NATIVE_WINDOW_TRANSFORM_FLIP_H; 342 } 343 } 344 // and apply to the current transform 345 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation(); 346 } 347 348 int winWidth = s.active.w; 349 int winHeight = s.active.h; 350 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 351 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 352 NATIVE_WINDOW_TRANSFORM_FLIP_H; 353 winWidth = s.active.h; 354 winHeight = s.active.w; 355 } 356 const Rect winCrop = activeCrop.transform( 357 invTransform, s.active.w, s.active.h); 358 359 // below, crop is intersected with winCrop expressed in crop's coordinate space 360 float xScale = crop.getWidth() / float(winWidth); 361 float yScale = crop.getHeight() / float(winHeight); 362 363 float insetL = winCrop.left * xScale; 364 float insetT = winCrop.top * yScale; 365 float insetR = (winWidth - winCrop.right ) * xScale; 366 float insetB = (winHeight - winCrop.bottom) * yScale; 367 368 crop.left += insetL; 369 crop.top += insetT; 370 crop.right -= insetR; 371 crop.bottom -= insetB; 372 } 373 return crop; 374} 375 376void Layer::setGeometry( 377 const sp<const DisplayDevice>& hw, 378 HWComposer::HWCLayerInterface& layer) 379{ 380 layer.setDefaultState(); 381 382 // enable this layer 383 layer.setSkip(false); 384 385 if (isSecure() && !hw->isSecure()) { 386 layer.setSkip(true); 387 } 388 389 // this gives us only the "orientation" component of the transform 390 const State& s(getDrawingState()); 391 if (!isOpaque(s) || s.alpha != 0xFF) { 392 layer.setBlending(mPremultipliedAlpha ? 393 HWC_BLENDING_PREMULT : 394 HWC_BLENDING_COVERAGE); 395 } 396 397 // apply the layer's transform, followed by the display's global transform 398 // here we're guaranteed that the layer's transform preserves rects 399 Rect frame(s.transform.transform(computeBounds())); 400 frame.intersect(hw->getViewport(), &frame); 401 const Transform& tr(hw->getTransform()); 402 layer.setFrame(tr.transform(frame)); 403 layer.setCrop(computeCrop(hw)); 404 layer.setPlaneAlpha(s.alpha); 405 406 /* 407 * Transformations are applied in this order: 408 * 1) buffer orientation/flip/mirror 409 * 2) state transformation (window manager) 410 * 3) layer orientation (screen orientation) 411 * (NOTE: the matrices are multiplied in reverse order) 412 */ 413 414 const Transform bufferOrientation(mCurrentTransform); 415 Transform transform(tr * s.transform * bufferOrientation); 416 417 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 418 /* 419 * the code below applies the display's inverse transform to the buffer 420 */ 421 uint32_t invTransform = hw->getOrientationTransform(); 422 uint32_t t_orientation = transform.getOrientation(); 423 // calculate the inverse transform 424 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 425 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 426 NATIVE_WINDOW_TRANSFORM_FLIP_H; 427 // If the transform has been rotated the axis of flip has been swapped 428 // so we need to swap which flip operations we are performing 429 bool is_h_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_H) != 0; 430 bool is_v_flipped = (t_orientation & NATIVE_WINDOW_TRANSFORM_FLIP_V) != 0; 431 if (is_h_flipped != is_v_flipped) { 432 t_orientation ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 433 NATIVE_WINDOW_TRANSFORM_FLIP_H; 434 } 435 } 436 // and apply to the current transform 437 transform = Transform(t_orientation) * Transform(invTransform); 438 } 439 440 // this gives us only the "orientation" component of the transform 441 const uint32_t orientation = transform.getOrientation(); 442 if (orientation & Transform::ROT_INVALID) { 443 // we can only handle simple transformation 444 layer.setSkip(true); 445 } else { 446 layer.setTransform(orientation); 447 } 448} 449 450void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 451 HWComposer::HWCLayerInterface& layer) { 452 // we have to set the visible region on every frame because 453 // we currently free it during onLayerDisplayed(), which is called 454 // after HWComposer::commit() -- every frame. 455 // Apply this display's projection's viewport to the visible region 456 // before giving it to the HWC HAL. 457 const Transform& tr = hw->getTransform(); 458 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); 459 layer.setVisibleRegionScreen(visible); 460 461 if (mSidebandStream.get()) { 462 layer.setSidebandStream(mSidebandStream); 463 } else { 464 // NOTE: buffer can be NULL if the client never drew into this 465 // layer yet, or if we ran out of memory 466 layer.setBuffer(mActiveBuffer); 467 } 468} 469 470void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, 471 HWComposer::HWCLayerInterface& layer) { 472 int fenceFd = -1; 473 474 // TODO: there is a possible optimization here: we only need to set the 475 // acquire fence the first time a new buffer is acquired on EACH display. 476 477 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) { 478 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 479 if (fence->isValid()) { 480 fenceFd = fence->dup(); 481 if (fenceFd == -1) { 482 ALOGW("failed to dup layer fence, skipping sync: %d", errno); 483 } 484 } 485 } 486 layer.setAcquireFenceFd(fenceFd); 487} 488 489Rect Layer::getPosition( 490 const sp<const DisplayDevice>& hw) 491{ 492 // this gives us only the "orientation" component of the transform 493 const State& s(getCurrentState()); 494 495 // apply the layer's transform, followed by the display's global transform 496 // here we're guaranteed that the layer's transform preserves rects 497 Rect win(s.active.w, s.active.h); 498 if (!s.active.crop.isEmpty()) { 499 win.intersect(s.active.crop, &win); 500 } 501 // subtract the transparent region and snap to the bounds 502 Rect bounds = reduce(win, s.activeTransparentRegion); 503 Rect frame(s.transform.transform(bounds)); 504 frame.intersect(hw->getViewport(), &frame); 505 const Transform& tr(hw->getTransform()); 506 return Rect(tr.transform(frame)); 507} 508 509// --------------------------------------------------------------------------- 510// drawing... 511// --------------------------------------------------------------------------- 512 513void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const { 514 onDraw(hw, clip, false); 515} 516 517void Layer::draw(const sp<const DisplayDevice>& hw, 518 bool useIdentityTransform) const { 519 onDraw(hw, Region(hw->bounds()), useIdentityTransform); 520} 521 522void Layer::draw(const sp<const DisplayDevice>& hw) const { 523 onDraw(hw, Region(hw->bounds()), false); 524} 525 526void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip, 527 bool useIdentityTransform) const 528{ 529 ATRACE_CALL(); 530 531 if (CC_UNLIKELY(mActiveBuffer == 0)) { 532 // the texture has not been created yet, this Layer has 533 // in fact never been drawn into. This happens frequently with 534 // SurfaceView because the WindowManager can't know when the client 535 // has drawn the first time. 536 537 // If there is nothing under us, we paint the screen in black, otherwise 538 // we just skip this update. 539 540 // figure out if there is something below us 541 Region under; 542 const SurfaceFlinger::LayerVector& drawingLayers( 543 mFlinger->mDrawingState.layersSortedByZ); 544 const size_t count = drawingLayers.size(); 545 for (size_t i=0 ; i<count ; ++i) { 546 const sp<Layer>& layer(drawingLayers[i]); 547 if (layer.get() == static_cast<Layer const*>(this)) 548 break; 549 under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 550 } 551 // if not everything below us is covered, we plug the holes! 552 Region holes(clip.subtract(under)); 553 if (!holes.isEmpty()) { 554 clearWithOpenGL(hw, holes, 0, 0, 0, 1); 555 } 556 return; 557 } 558 559 // Bind the current buffer to the GL texture, and wait for it to be 560 // ready for us to draw into. 561 status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 562 if (err != NO_ERROR) { 563 ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 564 // Go ahead and draw the buffer anyway; no matter what we do the screen 565 // is probably going to have something visibly wrong. 566 } 567 568 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 569 570 RenderEngine& engine(mFlinger->getRenderEngine()); 571 572 if (!blackOutLayer) { 573 // TODO: we could be more subtle with isFixedSize() 574 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 575 576 // Query the texture matrix given our current filtering mode. 577 float textureMatrix[16]; 578 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 579 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 580 581 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 582 583 /* 584 * the code below applies the display's inverse transform to the texture transform 585 */ 586 587 // create a 4x4 transform matrix from the display transform flags 588 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1); 589 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1); 590 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1); 591 592 mat4 tr; 593 uint32_t transform = hw->getOrientationTransform(); 594 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) 595 tr = tr * rot90; 596 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) 597 tr = tr * flipH; 598 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) 599 tr = tr * flipV; 600 601 // calculate the inverse 602 tr = inverse(tr); 603 604 // and finally apply it to the original texture matrix 605 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr); 606 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix)); 607 } 608 609 // Set things up for texturing. 610 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 611 mTexture.setFiltering(useFiltering); 612 mTexture.setMatrix(textureMatrix); 613 614 engine.setupLayerTexturing(mTexture); 615 } else { 616 engine.setupLayerBlackedOut(); 617 } 618 drawWithOpenGL(hw, clip, useIdentityTransform); 619 engine.disableTexturing(); 620} 621 622 623void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, 624 const Region& /* clip */, float red, float green, float blue, 625 float alpha) const 626{ 627 RenderEngine& engine(mFlinger->getRenderEngine()); 628 computeGeometry(hw, mMesh, false); 629 engine.setupFillWithColor(red, green, blue, alpha); 630 engine.drawMesh(mMesh); 631} 632 633void Layer::clearWithOpenGL( 634 const sp<const DisplayDevice>& hw, const Region& clip) const { 635 clearWithOpenGL(hw, clip, 0,0,0,0); 636} 637 638void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw, 639 const Region& /* clip */, bool useIdentityTransform) const { 640 const uint32_t fbHeight = hw->getHeight(); 641 const State& s(getDrawingState()); 642 643 computeGeometry(hw, mMesh, useIdentityTransform); 644 645 /* 646 * NOTE: the way we compute the texture coordinates here produces 647 * different results than when we take the HWC path -- in the later case 648 * the "source crop" is rounded to texel boundaries. 649 * This can produce significantly different results when the texture 650 * is scaled by a large amount. 651 * 652 * The GL code below is more logical (imho), and the difference with 653 * HWC is due to a limitation of the HWC API to integers -- a question 654 * is suspend is whether we should ignore this problem or revert to 655 * GL composition when a buffer scaling is applied (maybe with some 656 * minimal value)? Or, we could make GL behave like HWC -- but this feel 657 * like more of a hack. 658 */ 659 const Rect win(computeBounds()); 660 661 float left = float(win.left) / float(s.active.w); 662 float top = float(win.top) / float(s.active.h); 663 float right = float(win.right) / float(s.active.w); 664 float bottom = float(win.bottom) / float(s.active.h); 665 666 // TODO: we probably want to generate the texture coords with the mesh 667 // here we assume that we only have 4 vertices 668 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>()); 669 texCoords[0] = vec2(left, 1.0f - top); 670 texCoords[1] = vec2(left, 1.0f - bottom); 671 texCoords[2] = vec2(right, 1.0f - bottom); 672 texCoords[3] = vec2(right, 1.0f - top); 673 674 RenderEngine& engine(mFlinger->getRenderEngine()); 675 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha); 676 engine.drawMesh(mMesh); 677 engine.disableBlending(); 678} 679 680uint32_t Layer::getProducerStickyTransform() const { 681 int producerStickyTransform = 0; 682 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform); 683 if (ret != OK) { 684 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__, 685 strerror(-ret), ret); 686 return 0; 687 } 688 return static_cast<uint32_t>(producerStickyTransform); 689} 690 691void Layer::setFiltering(bool filtering) { 692 mFiltering = filtering; 693} 694 695bool Layer::getFiltering() const { 696 return mFiltering; 697} 698 699// As documented in libhardware header, formats in the range 700// 0x100 - 0x1FF are specific to the HAL implementation, and 701// are known to have no alpha channel 702// TODO: move definition for device-specific range into 703// hardware.h, instead of using hard-coded values here. 704#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 705 706bool Layer::getOpacityForFormat(uint32_t format) { 707 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 708 return true; 709 } 710 switch (format) { 711 case HAL_PIXEL_FORMAT_RGBA_8888: 712 case HAL_PIXEL_FORMAT_BGRA_8888: 713 case HAL_PIXEL_FORMAT_sRGB_A_8888: 714 return false; 715 } 716 // in all other case, we have no blending (also for unknown formats) 717 return true; 718} 719 720// ---------------------------------------------------------------------------- 721// local state 722// ---------------------------------------------------------------------------- 723 724void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh, 725 bool useIdentityTransform) const 726{ 727 const Layer::State& s(getDrawingState()); 728 const Transform tr(useIdentityTransform ? 729 hw->getTransform() : hw->getTransform() * s.transform); 730 const uint32_t hw_h = hw->getHeight(); 731 Rect win(s.active.w, s.active.h); 732 if (!s.active.crop.isEmpty()) { 733 win.intersect(s.active.crop, &win); 734 } 735 // subtract the transparent region and snap to the bounds 736 win = reduce(win, s.activeTransparentRegion); 737 738 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>()); 739 position[0] = tr.transform(win.left, win.top); 740 position[1] = tr.transform(win.left, win.bottom); 741 position[2] = tr.transform(win.right, win.bottom); 742 position[3] = tr.transform(win.right, win.top); 743 for (size_t i=0 ; i<4 ; i++) { 744 position[i].y = hw_h - position[i].y; 745 } 746} 747 748bool Layer::isOpaque(const Layer::State& s) const 749{ 750 // if we don't have a buffer yet, we're translucent regardless of the 751 // layer's opaque flag. 752 if (mActiveBuffer == 0) { 753 return false; 754 } 755 756 // if the layer has the opaque flag, then we're always opaque, 757 // otherwise we use the current buffer's format. 758 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity; 759} 760 761bool Layer::isProtected() const 762{ 763 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 764 return (activeBuffer != 0) && 765 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 766} 767 768bool Layer::isFixedSize() const { 769 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 770} 771 772bool Layer::isCropped() const { 773 return !mCurrentCrop.isEmpty(); 774} 775 776bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const { 777 return mNeedsFiltering || hw->needsFiltering(); 778} 779 780void Layer::setVisibleRegion(const Region& visibleRegion) { 781 // always called from main thread 782 this->visibleRegion = visibleRegion; 783} 784 785void Layer::setCoveredRegion(const Region& coveredRegion) { 786 // always called from main thread 787 this->coveredRegion = coveredRegion; 788} 789 790void Layer::setVisibleNonTransparentRegion(const Region& 791 setVisibleNonTransparentRegion) { 792 // always called from main thread 793 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; 794} 795 796// ---------------------------------------------------------------------------- 797// transaction 798// ---------------------------------------------------------------------------- 799 800uint32_t Layer::doTransaction(uint32_t flags) { 801 ATRACE_CALL(); 802 803 const Layer::State& s(getDrawingState()); 804 const Layer::State& c(getCurrentState()); 805 806 const bool sizeChanged = (c.requested.w != s.requested.w) || 807 (c.requested.h != s.requested.h); 808 809 if (sizeChanged) { 810 // the size changed, we need to ask our client to request a new buffer 811 ALOGD_IF(DEBUG_RESIZE, 812 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 813 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 814 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 815 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 816 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 817 this, getName().string(), mCurrentTransform, mCurrentScalingMode, 818 c.active.w, c.active.h, 819 c.active.crop.left, 820 c.active.crop.top, 821 c.active.crop.right, 822 c.active.crop.bottom, 823 c.active.crop.getWidth(), 824 c.active.crop.getHeight(), 825 c.requested.w, c.requested.h, 826 c.requested.crop.left, 827 c.requested.crop.top, 828 c.requested.crop.right, 829 c.requested.crop.bottom, 830 c.requested.crop.getWidth(), 831 c.requested.crop.getHeight(), 832 s.active.w, s.active.h, 833 s.active.crop.left, 834 s.active.crop.top, 835 s.active.crop.right, 836 s.active.crop.bottom, 837 s.active.crop.getWidth(), 838 s.active.crop.getHeight(), 839 s.requested.w, s.requested.h, 840 s.requested.crop.left, 841 s.requested.crop.top, 842 s.requested.crop.right, 843 s.requested.crop.bottom, 844 s.requested.crop.getWidth(), 845 s.requested.crop.getHeight()); 846 847 // record the new size, form this point on, when the client request 848 // a buffer, it'll get the new size. 849 mSurfaceFlingerConsumer->setDefaultBufferSize( 850 c.requested.w, c.requested.h); 851 } 852 853 if (!isFixedSize()) { 854 855 const bool resizePending = (c.requested.w != c.active.w) || 856 (c.requested.h != c.active.h); 857 858 if (resizePending) { 859 // don't let Layer::doTransaction update the drawing state 860 // if we have a pending resize, unless we are in fixed-size mode. 861 // the drawing state will be updated only once we receive a buffer 862 // with the correct size. 863 // 864 // in particular, we want to make sure the clip (which is part 865 // of the geometry state) is latched together with the size but is 866 // latched immediately when no resizing is involved. 867 868 flags |= eDontUpdateGeometryState; 869 } 870 } 871 872 // always set active to requested, unless we're asked not to 873 // this is used by Layer, which special cases resizes. 874 if (flags & eDontUpdateGeometryState) { 875 } else { 876 Layer::State& editCurrentState(getCurrentState()); 877 editCurrentState.active = c.requested; 878 } 879 880 if (s.active != c.active) { 881 // invalidate and recompute the visible regions if needed 882 flags |= Layer::eVisibleRegion; 883 } 884 885 if (c.sequence != s.sequence) { 886 // invalidate and recompute the visible regions if needed 887 flags |= eVisibleRegion; 888 this->contentDirty = true; 889 890 // we may use linear filtering, if the matrix scales us 891 const uint8_t type = c.transform.getType(); 892 mNeedsFiltering = (!c.transform.preserveRects() || 893 (type >= Transform::SCALE)); 894 } 895 896 // Commit the transaction 897 commitTransaction(); 898 return flags; 899} 900 901void Layer::commitTransaction() { 902 mDrawingState = mCurrentState; 903} 904 905uint32_t Layer::getTransactionFlags(uint32_t flags) { 906 return android_atomic_and(~flags, &mTransactionFlags) & flags; 907} 908 909uint32_t Layer::setTransactionFlags(uint32_t flags) { 910 return android_atomic_or(flags, &mTransactionFlags); 911} 912 913bool Layer::setPosition(float x, float y) { 914 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 915 return false; 916 mCurrentState.sequence++; 917 mCurrentState.transform.set(x, y); 918 setTransactionFlags(eTransactionNeeded); 919 return true; 920} 921bool Layer::setLayer(uint32_t z) { 922 if (mCurrentState.z == z) 923 return false; 924 mCurrentState.sequence++; 925 mCurrentState.z = z; 926 setTransactionFlags(eTransactionNeeded); 927 return true; 928} 929bool Layer::setSize(uint32_t w, uint32_t h) { 930 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) 931 return false; 932 mCurrentState.requested.w = w; 933 mCurrentState.requested.h = h; 934 setTransactionFlags(eTransactionNeeded); 935 return true; 936} 937bool Layer::setAlpha(uint8_t alpha) { 938 if (mCurrentState.alpha == alpha) 939 return false; 940 mCurrentState.sequence++; 941 mCurrentState.alpha = alpha; 942 setTransactionFlags(eTransactionNeeded); 943 return true; 944} 945bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { 946 mCurrentState.sequence++; 947 mCurrentState.transform.set( 948 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 949 setTransactionFlags(eTransactionNeeded); 950 return true; 951} 952bool Layer::setTransparentRegionHint(const Region& transparent) { 953 mCurrentState.requestedTransparentRegion = transparent; 954 setTransactionFlags(eTransactionNeeded); 955 return true; 956} 957bool Layer::setFlags(uint8_t flags, uint8_t mask) { 958 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 959 if (mCurrentState.flags == newFlags) 960 return false; 961 mCurrentState.sequence++; 962 mCurrentState.flags = newFlags; 963 setTransactionFlags(eTransactionNeeded); 964 return true; 965} 966bool Layer::setCrop(const Rect& crop) { 967 if (mCurrentState.requested.crop == crop) 968 return false; 969 mCurrentState.sequence++; 970 mCurrentState.requested.crop = crop; 971 setTransactionFlags(eTransactionNeeded); 972 return true; 973} 974 975bool Layer::setLayerStack(uint32_t layerStack) { 976 if (mCurrentState.layerStack == layerStack) 977 return false; 978 mCurrentState.sequence++; 979 mCurrentState.layerStack = layerStack; 980 setTransactionFlags(eTransactionNeeded); 981 return true; 982} 983 984// ---------------------------------------------------------------------------- 985// pageflip handling... 986// ---------------------------------------------------------------------------- 987 988bool Layer::onPreComposition() { 989 mRefreshPending = false; 990 return mQueuedFrames > 0 || mSidebandStreamChanged; 991} 992 993void Layer::onPostComposition() { 994 if (mFrameLatencyNeeded) { 995 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 996 mFrameTracker.setDesiredPresentTime(desiredPresentTime); 997 998 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 999 if (frameReadyFence->isValid()) { 1000 mFrameTracker.setFrameReadyFence(frameReadyFence); 1001 } else { 1002 // There was no fence for this frame, so assume that it was ready 1003 // to be presented at the desired present time. 1004 mFrameTracker.setFrameReadyTime(desiredPresentTime); 1005 } 1006 1007 const HWComposer& hwc = mFlinger->getHwComposer(); 1008 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 1009 if (presentFence->isValid()) { 1010 mFrameTracker.setActualPresentFence(presentFence); 1011 } else { 1012 // The HWC doesn't support present fences, so use the refresh 1013 // timestamp instead. 1014 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 1015 mFrameTracker.setActualPresentTime(presentTime); 1016 } 1017 1018 mFrameTracker.advanceFrame(); 1019 mFrameLatencyNeeded = false; 1020 } 1021} 1022 1023bool Layer::isVisible() const { 1024 const Layer::State& s(mDrawingState); 1025 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha 1026 && (mActiveBuffer != NULL || mSidebandStream != NULL); 1027} 1028 1029Region Layer::latchBuffer(bool& recomputeVisibleRegions) 1030{ 1031 ATRACE_CALL(); 1032 1033 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) { 1034 // mSidebandStreamChanged was true 1035 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); 1036 } 1037 1038 Region outDirtyRegion; 1039 if (mQueuedFrames > 0) { 1040 1041 // if we've already called updateTexImage() without going through 1042 // a composition step, we have to skip this layer at this point 1043 // because we cannot call updateTeximage() without a corresponding 1044 // compositionComplete() call. 1045 // we'll trigger an update in onPreComposition(). 1046 if (mRefreshPending) { 1047 return outDirtyRegion; 1048 } 1049 1050 // Capture the old state of the layer for comparisons later 1051 const State& s(getDrawingState()); 1052 const bool oldOpacity = isOpaque(s); 1053 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 1054 1055 struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 1056 Layer::State& front; 1057 Layer::State& current; 1058 bool& recomputeVisibleRegions; 1059 bool stickyTransformSet; 1060 Reject(Layer::State& front, Layer::State& current, 1061 bool& recomputeVisibleRegions, bool stickySet) 1062 : front(front), current(current), 1063 recomputeVisibleRegions(recomputeVisibleRegions), 1064 stickyTransformSet(stickySet) { 1065 } 1066 1067 virtual bool reject(const sp<GraphicBuffer>& buf, 1068 const IGraphicBufferConsumer::BufferItem& item) { 1069 if (buf == NULL) { 1070 return false; 1071 } 1072 1073 uint32_t bufWidth = buf->getWidth(); 1074 uint32_t bufHeight = buf->getHeight(); 1075 1076 // check that we received a buffer of the right size 1077 // (Take the buffer's orientation into account) 1078 if (item.mTransform & Transform::ROT_90) { 1079 swap(bufWidth, bufHeight); 1080 } 1081 1082 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 1083 if (front.active != front.requested) { 1084 1085 if (isFixedSize || 1086 (bufWidth == front.requested.w && 1087 bufHeight == front.requested.h)) 1088 { 1089 // Here we pretend the transaction happened by updating the 1090 // current and drawing states. Drawing state is only accessed 1091 // in this thread, no need to have it locked 1092 front.active = front.requested; 1093 1094 // We also need to update the current state so that 1095 // we don't end-up overwriting the drawing state with 1096 // this stale current state during the next transaction 1097 // 1098 // NOTE: We don't need to hold the transaction lock here 1099 // because State::active is only accessed from this thread. 1100 current.active = front.active; 1101 1102 // recompute visible region 1103 recomputeVisibleRegions = true; 1104 } 1105 1106 ALOGD_IF(DEBUG_RESIZE, 1107 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 1108 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 1109 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 1110 bufWidth, bufHeight, item.mTransform, item.mScalingMode, 1111 front.active.w, front.active.h, 1112 front.active.crop.left, 1113 front.active.crop.top, 1114 front.active.crop.right, 1115 front.active.crop.bottom, 1116 front.active.crop.getWidth(), 1117 front.active.crop.getHeight(), 1118 front.requested.w, front.requested.h, 1119 front.requested.crop.left, 1120 front.requested.crop.top, 1121 front.requested.crop.right, 1122 front.requested.crop.bottom, 1123 front.requested.crop.getWidth(), 1124 front.requested.crop.getHeight()); 1125 } 1126 1127 if (!isFixedSize && !stickyTransformSet) { 1128 if (front.active.w != bufWidth || 1129 front.active.h != bufHeight) { 1130 // reject this buffer 1131 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}", 1132 bufWidth, bufHeight, front.active.w, front.active.h); 1133 return true; 1134 } 1135 } 1136 1137 // if the transparent region has changed (this test is 1138 // conservative, but that's fine, worst case we're doing 1139 // a bit of extra work), we latch the new one and we 1140 // trigger a visible-region recompute. 1141 if (!front.activeTransparentRegion.isTriviallyEqual( 1142 front.requestedTransparentRegion)) { 1143 front.activeTransparentRegion = front.requestedTransparentRegion; 1144 1145 // We also need to update the current state so that 1146 // we don't end-up overwriting the drawing state with 1147 // this stale current state during the next transaction 1148 // 1149 // NOTE: We don't need to hold the transaction lock here 1150 // because State::active is only accessed from this thread. 1151 current.activeTransparentRegion = front.activeTransparentRegion; 1152 1153 // recompute visible region 1154 recomputeVisibleRegions = true; 1155 } 1156 1157 return false; 1158 } 1159 }; 1160 1161 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, 1162 getProducerStickyTransform() != 0); 1163 1164 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r, 1165 mFlinger->mPrimaryDispSync); 1166 if (updateResult == BufferQueue::PRESENT_LATER) { 1167 // Producer doesn't want buffer to be displayed yet. Signal a 1168 // layer update so we check again at the next opportunity. 1169 mFlinger->signalLayerUpdate(); 1170 return outDirtyRegion; 1171 } 1172 1173 // Decrement the queued-frames count. Signal another event if we 1174 // have more frames pending. 1175 if (android_atomic_dec(&mQueuedFrames) > 1) { 1176 mFlinger->signalLayerUpdate(); 1177 } 1178 1179 if (updateResult != NO_ERROR) { 1180 // something happened! 1181 recomputeVisibleRegions = true; 1182 return outDirtyRegion; 1183 } 1184 1185 // update the active buffer 1186 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 1187 if (mActiveBuffer == NULL) { 1188 // this can only happen if the very first buffer was rejected. 1189 return outDirtyRegion; 1190 } 1191 1192 mRefreshPending = true; 1193 mFrameLatencyNeeded = true; 1194 if (oldActiveBuffer == NULL) { 1195 // the first time we receive a buffer, we need to trigger a 1196 // geometry invalidation. 1197 recomputeVisibleRegions = true; 1198 } 1199 1200 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 1201 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 1202 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 1203 if ((crop != mCurrentCrop) || 1204 (transform != mCurrentTransform) || 1205 (scalingMode != mCurrentScalingMode)) 1206 { 1207 mCurrentCrop = crop; 1208 mCurrentTransform = transform; 1209 mCurrentScalingMode = scalingMode; 1210 recomputeVisibleRegions = true; 1211 } 1212 1213 if (oldActiveBuffer != NULL) { 1214 uint32_t bufWidth = mActiveBuffer->getWidth(); 1215 uint32_t bufHeight = mActiveBuffer->getHeight(); 1216 if (bufWidth != uint32_t(oldActiveBuffer->width) || 1217 bufHeight != uint32_t(oldActiveBuffer->height)) { 1218 recomputeVisibleRegions = true; 1219 } 1220 } 1221 1222 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 1223 if (oldOpacity != isOpaque(s)) { 1224 recomputeVisibleRegions = true; 1225 } 1226 1227 // FIXME: postedRegion should be dirty & bounds 1228 Region dirtyRegion(Rect(s.active.w, s.active.h)); 1229 1230 // transform the dirty region to window-manager space 1231 outDirtyRegion = (s.transform.transform(dirtyRegion)); 1232 } 1233 return outDirtyRegion; 1234} 1235 1236uint32_t Layer::getEffectiveUsage(uint32_t usage) const 1237{ 1238 // TODO: should we do something special if mSecure is set? 1239 if (mProtectedByApp) { 1240 // need a hardware-protected path to external video sink 1241 usage |= GraphicBuffer::USAGE_PROTECTED; 1242 } 1243 if (mPotentialCursor) { 1244 usage |= GraphicBuffer::USAGE_CURSOR; 1245 } 1246 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 1247 return usage; 1248} 1249 1250void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 1251 uint32_t orientation = 0; 1252 if (!mFlinger->mDebugDisableTransformHint) { 1253 // The transform hint is used to improve performance, but we can 1254 // only have a single transform hint, it cannot 1255 // apply to all displays. 1256 const Transform& planeTransform(hw->getTransform()); 1257 orientation = planeTransform.getOrientation(); 1258 if (orientation & Transform::ROT_INVALID) { 1259 orientation = 0; 1260 } 1261 } 1262 mSurfaceFlingerConsumer->setTransformHint(orientation); 1263} 1264 1265// ---------------------------------------------------------------------------- 1266// debugging 1267// ---------------------------------------------------------------------------- 1268 1269void Layer::dump(String8& result, Colorizer& colorizer) const 1270{ 1271 const Layer::State& s(getDrawingState()); 1272 1273 colorizer.colorize(result, Colorizer::GREEN); 1274 result.appendFormat( 1275 "+ %s %p (%s)\n", 1276 getTypeId(), this, getName().string()); 1277 colorizer.reset(result); 1278 1279 s.activeTransparentRegion.dump(result, "transparentRegion"); 1280 visibleRegion.dump(result, "visibleRegion"); 1281 sp<Client> client(mClientRef.promote()); 1282 1283 result.appendFormat( " " 1284 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), " 1285 "isOpaque=%1d, invalidate=%1d, " 1286 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n" 1287 " client=%p\n", 1288 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h, 1289 s.active.crop.left, s.active.crop.top, 1290 s.active.crop.right, s.active.crop.bottom, 1291 isOpaque(s), contentDirty, 1292 s.alpha, s.flags, 1293 s.transform[0][0], s.transform[0][1], 1294 s.transform[1][0], s.transform[1][1], 1295 client.get()); 1296 1297 sp<const GraphicBuffer> buf0(mActiveBuffer); 1298 uint32_t w0=0, h0=0, s0=0, f0=0; 1299 if (buf0 != 0) { 1300 w0 = buf0->getWidth(); 1301 h0 = buf0->getHeight(); 1302 s0 = buf0->getStride(); 1303 f0 = buf0->format; 1304 } 1305 result.appendFormat( 1306 " " 1307 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 1308 " queued-frames=%d, mRefreshPending=%d\n", 1309 mFormat, w0, h0, s0,f0, 1310 mQueuedFrames, mRefreshPending); 1311 1312 if (mSurfaceFlingerConsumer != 0) { 1313 mSurfaceFlingerConsumer->dump(result, " "); 1314 } 1315} 1316 1317void Layer::dumpFrameStats(String8& result) const { 1318 mFrameTracker.dumpStats(result); 1319} 1320 1321void Layer::clearFrameStats() { 1322 mFrameTracker.clearStats(); 1323} 1324 1325void Layer::logFrameStats() { 1326 mFrameTracker.logAndResetStats(mName); 1327} 1328 1329void Layer::getFrameStats(FrameStats* outStats) const { 1330 mFrameTracker.getStats(outStats); 1331} 1332 1333// --------------------------------------------------------------------------- 1334 1335Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, 1336 const sp<Layer>& layer) 1337 : mFlinger(flinger), mLayer(layer) { 1338} 1339 1340Layer::LayerCleaner::~LayerCleaner() { 1341 // destroy client resources 1342 mFlinger->onLayerDestroyed(mLayer); 1343} 1344 1345// --------------------------------------------------------------------------- 1346}; // namespace android 1347 1348#if defined(__gl_h_) 1349#error "don't include gl/gl.h in this file" 1350#endif 1351 1352#if defined(__gl2_h_) 1353#error "don't include gl2/gl2.h in this file" 1354#endif 1355