Layer.cpp revision f75514079434cefcdb746e8b083708d6de5f86ff
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 } 336 // and apply to the current transform 337 invTransform = (Transform(invTransform) * Transform(invTransformOrient)).getOrientation(); 338 } 339 340 int winWidth = s.active.w; 341 int winHeight = s.active.h; 342 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 343 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 344 NATIVE_WINDOW_TRANSFORM_FLIP_H; 345 winWidth = s.active.h; 346 winHeight = s.active.w; 347 } 348 const Rect winCrop = activeCrop.transform( 349 invTransform, s.active.w, s.active.h); 350 351 // below, crop is intersected with winCrop expressed in crop's coordinate space 352 float xScale = crop.getWidth() / float(winWidth); 353 float yScale = crop.getHeight() / float(winHeight); 354 355 float insetL = winCrop.left * xScale; 356 float insetT = winCrop.top * yScale; 357 float insetR = (winWidth - winCrop.right ) * xScale; 358 float insetB = (winHeight - winCrop.bottom) * yScale; 359 360 crop.left += insetL; 361 crop.top += insetT; 362 crop.right -= insetR; 363 crop.bottom -= insetB; 364 } 365 return crop; 366} 367 368void Layer::setGeometry( 369 const sp<const DisplayDevice>& hw, 370 HWComposer::HWCLayerInterface& layer) 371{ 372 layer.setDefaultState(); 373 374 // enable this layer 375 layer.setSkip(false); 376 377 if (isSecure() && !hw->isSecure()) { 378 layer.setSkip(true); 379 } 380 381 // this gives us only the "orientation" component of the transform 382 const State& s(getDrawingState()); 383 if (!isOpaque(s) || s.alpha != 0xFF) { 384 layer.setBlending(mPremultipliedAlpha ? 385 HWC_BLENDING_PREMULT : 386 HWC_BLENDING_COVERAGE); 387 } 388 389 // apply the layer's transform, followed by the display's global transform 390 // here we're guaranteed that the layer's transform preserves rects 391 Rect frame(s.transform.transform(computeBounds())); 392 frame.intersect(hw->getViewport(), &frame); 393 const Transform& tr(hw->getTransform()); 394 layer.setFrame(tr.transform(frame)); 395 layer.setCrop(computeCrop(hw)); 396 layer.setPlaneAlpha(s.alpha); 397 398 /* 399 * Transformations are applied in this order: 400 * 1) buffer orientation/flip/mirror 401 * 2) state transformation (window manager) 402 * 3) layer orientation (screen orientation) 403 * (NOTE: the matrices are multiplied in reverse order) 404 */ 405 406 const Transform bufferOrientation(mCurrentTransform); 407 Transform transform(tr * s.transform * bufferOrientation); 408 409 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 410 /* 411 * the code below applies the display's inverse transform to the buffer 412 */ 413 uint32_t invTransform = hw->getOrientationTransform(); 414 // calculate the inverse transform 415 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 416 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 417 NATIVE_WINDOW_TRANSFORM_FLIP_H; 418 } 419 // and apply to the current transform 420 transform = transform * Transform(invTransform); 421 } 422 423 // this gives us only the "orientation" component of the transform 424 const uint32_t orientation = transform.getOrientation(); 425 if (orientation & Transform::ROT_INVALID) { 426 // we can only handle simple transformation 427 layer.setSkip(true); 428 } else { 429 layer.setTransform(orientation); 430 } 431} 432 433void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 434 HWComposer::HWCLayerInterface& layer) { 435 // we have to set the visible region on every frame because 436 // we currently free it during onLayerDisplayed(), which is called 437 // after HWComposer::commit() -- every frame. 438 // Apply this display's projection's viewport to the visible region 439 // before giving it to the HWC HAL. 440 const Transform& tr = hw->getTransform(); 441 Region visible = tr.transform(visibleRegion.intersect(hw->getViewport())); 442 layer.setVisibleRegionScreen(visible); 443 444 if (mSidebandStream.get()) { 445 layer.setSidebandStream(mSidebandStream); 446 } else { 447 // NOTE: buffer can be NULL if the client never drew into this 448 // layer yet, or if we ran out of memory 449 layer.setBuffer(mActiveBuffer); 450 } 451} 452 453void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */, 454 HWComposer::HWCLayerInterface& layer) { 455 int fenceFd = -1; 456 457 // TODO: there is a possible optimization here: we only need to set the 458 // acquire fence the first time a new buffer is acquired on EACH display. 459 460 if (layer.getCompositionType() == HWC_OVERLAY || layer.getCompositionType() == HWC_CURSOR_OVERLAY) { 461 sp<Fence> fence = mSurfaceFlingerConsumer->getCurrentFence(); 462 if (fence->isValid()) { 463 fenceFd = fence->dup(); 464 if (fenceFd == -1) { 465 ALOGW("failed to dup layer fence, skipping sync: %d", errno); 466 } 467 } 468 } 469 layer.setAcquireFenceFd(fenceFd); 470} 471 472Rect Layer::getPosition( 473 const sp<const DisplayDevice>& hw) 474{ 475 // this gives us only the "orientation" component of the transform 476 const State& s(getCurrentState()); 477 478 // apply the layer's transform, followed by the display's global transform 479 // here we're guaranteed that the layer's transform preserves rects 480 Rect win(s.active.w, s.active.h); 481 if (!s.active.crop.isEmpty()) { 482 win.intersect(s.active.crop, &win); 483 } 484 // subtract the transparent region and snap to the bounds 485 Rect bounds = reduce(win, s.activeTransparentRegion); 486 Rect frame(s.transform.transform(bounds)); 487 frame.intersect(hw->getViewport(), &frame); 488 const Transform& tr(hw->getTransform()); 489 return Rect(tr.transform(frame)); 490} 491 492// --------------------------------------------------------------------------- 493// drawing... 494// --------------------------------------------------------------------------- 495 496void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const { 497 onDraw(hw, clip, false); 498} 499 500void Layer::draw(const sp<const DisplayDevice>& hw, 501 bool useIdentityTransform) const { 502 onDraw(hw, Region(hw->bounds()), useIdentityTransform); 503} 504 505void Layer::draw(const sp<const DisplayDevice>& hw) const { 506 onDraw(hw, Region(hw->bounds()), false); 507} 508 509void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip, 510 bool useIdentityTransform) const 511{ 512 ATRACE_CALL(); 513 514 if (CC_UNLIKELY(mActiveBuffer == 0)) { 515 // the texture has not been created yet, this Layer has 516 // in fact never been drawn into. This happens frequently with 517 // SurfaceView because the WindowManager can't know when the client 518 // has drawn the first time. 519 520 // If there is nothing under us, we paint the screen in black, otherwise 521 // we just skip this update. 522 523 // figure out if there is something below us 524 Region under; 525 const SurfaceFlinger::LayerVector& drawingLayers( 526 mFlinger->mDrawingState.layersSortedByZ); 527 const size_t count = drawingLayers.size(); 528 for (size_t i=0 ; i<count ; ++i) { 529 const sp<Layer>& layer(drawingLayers[i]); 530 if (layer.get() == static_cast<Layer const*>(this)) 531 break; 532 under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 533 } 534 // if not everything below us is covered, we plug the holes! 535 Region holes(clip.subtract(under)); 536 if (!holes.isEmpty()) { 537 clearWithOpenGL(hw, holes, 0, 0, 0, 1); 538 } 539 return; 540 } 541 542 // Bind the current buffer to the GL texture, and wait for it to be 543 // ready for us to draw into. 544 status_t err = mSurfaceFlingerConsumer->bindTextureImage(); 545 if (err != NO_ERROR) { 546 ALOGW("onDraw: bindTextureImage failed (err=%d)", err); 547 // Go ahead and draw the buffer anyway; no matter what we do the screen 548 // is probably going to have something visibly wrong. 549 } 550 551 bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure()); 552 553 RenderEngine& engine(mFlinger->getRenderEngine()); 554 555 if (!blackOutLayer) { 556 // TODO: we could be more subtle with isFixedSize() 557 const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize(); 558 559 // Query the texture matrix given our current filtering mode. 560 float textureMatrix[16]; 561 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering); 562 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix); 563 564 if (mSurfaceFlingerConsumer->getTransformToDisplayInverse()) { 565 566 /* 567 * the code below applies the display's inverse transform to the texture transform 568 */ 569 570 // create a 4x4 transform matrix from the display transform flags 571 const mat4 flipH(-1,0,0,0, 0,1,0,0, 0,0,1,0, 1,0,0,1); 572 const mat4 flipV( 1,0,0,0, 0,-1,0,0, 0,0,1,0, 0,1,0,1); 573 const mat4 rot90( 0,1,0,0, -1,0,0,0, 0,0,1,0, 1,0,0,1); 574 575 mat4 tr; 576 uint32_t transform = hw->getOrientationTransform(); 577 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) 578 tr = tr * rot90; 579 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) 580 tr = tr * flipH; 581 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) 582 tr = tr * flipV; 583 584 // calculate the inverse 585 tr = inverse(tr); 586 587 // and finally apply it to the original texture matrix 588 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr); 589 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix)); 590 } 591 592 // Set things up for texturing. 593 mTexture.setDimensions(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 594 mTexture.setFiltering(useFiltering); 595 mTexture.setMatrix(textureMatrix); 596 597 engine.setupLayerTexturing(mTexture); 598 } else { 599 engine.setupLayerBlackedOut(); 600 } 601 drawWithOpenGL(hw, clip, useIdentityTransform); 602 engine.disableTexturing(); 603} 604 605 606void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, 607 const Region& /* clip */, float red, float green, float blue, 608 float alpha) const 609{ 610 RenderEngine& engine(mFlinger->getRenderEngine()); 611 computeGeometry(hw, mMesh, false); 612 engine.setupFillWithColor(red, green, blue, alpha); 613 engine.drawMesh(mMesh); 614} 615 616void Layer::clearWithOpenGL( 617 const sp<const DisplayDevice>& hw, const Region& clip) const { 618 clearWithOpenGL(hw, clip, 0,0,0,0); 619} 620 621void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw, 622 const Region& /* clip */, bool useIdentityTransform) const { 623 const uint32_t fbHeight = hw->getHeight(); 624 const State& s(getDrawingState()); 625 626 computeGeometry(hw, mMesh, useIdentityTransform); 627 628 /* 629 * NOTE: the way we compute the texture coordinates here produces 630 * different results than when we take the HWC path -- in the later case 631 * the "source crop" is rounded to texel boundaries. 632 * This can produce significantly different results when the texture 633 * is scaled by a large amount. 634 * 635 * The GL code below is more logical (imho), and the difference with 636 * HWC is due to a limitation of the HWC API to integers -- a question 637 * is suspend is whether we should ignore this problem or revert to 638 * GL composition when a buffer scaling is applied (maybe with some 639 * minimal value)? Or, we could make GL behave like HWC -- but this feel 640 * like more of a hack. 641 */ 642 const Rect win(computeBounds()); 643 644 float left = float(win.left) / float(s.active.w); 645 float top = float(win.top) / float(s.active.h); 646 float right = float(win.right) / float(s.active.w); 647 float bottom = float(win.bottom) / float(s.active.h); 648 649 // TODO: we probably want to generate the texture coords with the mesh 650 // here we assume that we only have 4 vertices 651 Mesh::VertexArray<vec2> texCoords(mMesh.getTexCoordArray<vec2>()); 652 texCoords[0] = vec2(left, 1.0f - top); 653 texCoords[1] = vec2(left, 1.0f - bottom); 654 texCoords[2] = vec2(right, 1.0f - bottom); 655 texCoords[3] = vec2(right, 1.0f - top); 656 657 RenderEngine& engine(mFlinger->getRenderEngine()); 658 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha); 659 engine.drawMesh(mMesh); 660 engine.disableBlending(); 661} 662 663uint32_t Layer::getProducerStickyTransform() const { 664 int producerStickyTransform = 0; 665 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform); 666 if (ret != OK) { 667 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__, 668 strerror(-ret), ret); 669 return 0; 670 } 671 return static_cast<uint32_t>(producerStickyTransform); 672} 673 674void Layer::setFiltering(bool filtering) { 675 mFiltering = filtering; 676} 677 678bool Layer::getFiltering() const { 679 return mFiltering; 680} 681 682// As documented in libhardware header, formats in the range 683// 0x100 - 0x1FF are specific to the HAL implementation, and 684// are known to have no alpha channel 685// TODO: move definition for device-specific range into 686// hardware.h, instead of using hard-coded values here. 687#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 688 689bool Layer::getOpacityForFormat(uint32_t format) { 690 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 691 return true; 692 } 693 switch (format) { 694 case HAL_PIXEL_FORMAT_RGBA_8888: 695 case HAL_PIXEL_FORMAT_BGRA_8888: 696 case HAL_PIXEL_FORMAT_sRGB_A_8888: 697 return false; 698 } 699 // in all other case, we have no blending (also for unknown formats) 700 return true; 701} 702 703// ---------------------------------------------------------------------------- 704// local state 705// ---------------------------------------------------------------------------- 706 707void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh, 708 bool useIdentityTransform) const 709{ 710 const Layer::State& s(getDrawingState()); 711 const Transform tr(useIdentityTransform ? 712 hw->getTransform() : hw->getTransform() * s.transform); 713 const uint32_t hw_h = hw->getHeight(); 714 Rect win(s.active.w, s.active.h); 715 if (!s.active.crop.isEmpty()) { 716 win.intersect(s.active.crop, &win); 717 } 718 // subtract the transparent region and snap to the bounds 719 win = reduce(win, s.activeTransparentRegion); 720 721 Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>()); 722 position[0] = tr.transform(win.left, win.top); 723 position[1] = tr.transform(win.left, win.bottom); 724 position[2] = tr.transform(win.right, win.bottom); 725 position[3] = tr.transform(win.right, win.top); 726 for (size_t i=0 ; i<4 ; i++) { 727 position[i].y = hw_h - position[i].y; 728 } 729} 730 731bool Layer::isOpaque(const Layer::State& s) const 732{ 733 // if we don't have a buffer yet, we're translucent regardless of the 734 // layer's opaque flag. 735 if (mActiveBuffer == 0) { 736 return false; 737 } 738 739 // if the layer has the opaque flag, then we're always opaque, 740 // otherwise we use the current buffer's format. 741 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity; 742} 743 744bool Layer::isProtected() const 745{ 746 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 747 return (activeBuffer != 0) && 748 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 749} 750 751bool Layer::isFixedSize() const { 752 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 753} 754 755bool Layer::isCropped() const { 756 return !mCurrentCrop.isEmpty(); 757} 758 759bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const { 760 return mNeedsFiltering || hw->needsFiltering(); 761} 762 763void Layer::setVisibleRegion(const Region& visibleRegion) { 764 // always called from main thread 765 this->visibleRegion = visibleRegion; 766} 767 768void Layer::setCoveredRegion(const Region& coveredRegion) { 769 // always called from main thread 770 this->coveredRegion = coveredRegion; 771} 772 773void Layer::setVisibleNonTransparentRegion(const Region& 774 setVisibleNonTransparentRegion) { 775 // always called from main thread 776 this->visibleNonTransparentRegion = setVisibleNonTransparentRegion; 777} 778 779// ---------------------------------------------------------------------------- 780// transaction 781// ---------------------------------------------------------------------------- 782 783uint32_t Layer::doTransaction(uint32_t flags) { 784 ATRACE_CALL(); 785 786 const Layer::State& s(getDrawingState()); 787 const Layer::State& c(getCurrentState()); 788 789 const bool sizeChanged = (c.requested.w != s.requested.w) || 790 (c.requested.h != s.requested.h); 791 792 if (sizeChanged) { 793 // the size changed, we need to ask our client to request a new buffer 794 ALOGD_IF(DEBUG_RESIZE, 795 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 796 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 797 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 798 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 799 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 800 this, getName().string(), mCurrentTransform, mCurrentScalingMode, 801 c.active.w, c.active.h, 802 c.active.crop.left, 803 c.active.crop.top, 804 c.active.crop.right, 805 c.active.crop.bottom, 806 c.active.crop.getWidth(), 807 c.active.crop.getHeight(), 808 c.requested.w, c.requested.h, 809 c.requested.crop.left, 810 c.requested.crop.top, 811 c.requested.crop.right, 812 c.requested.crop.bottom, 813 c.requested.crop.getWidth(), 814 c.requested.crop.getHeight(), 815 s.active.w, s.active.h, 816 s.active.crop.left, 817 s.active.crop.top, 818 s.active.crop.right, 819 s.active.crop.bottom, 820 s.active.crop.getWidth(), 821 s.active.crop.getHeight(), 822 s.requested.w, s.requested.h, 823 s.requested.crop.left, 824 s.requested.crop.top, 825 s.requested.crop.right, 826 s.requested.crop.bottom, 827 s.requested.crop.getWidth(), 828 s.requested.crop.getHeight()); 829 830 // record the new size, form this point on, when the client request 831 // a buffer, it'll get the new size. 832 mSurfaceFlingerConsumer->setDefaultBufferSize( 833 c.requested.w, c.requested.h); 834 } 835 836 if (!isFixedSize()) { 837 838 const bool resizePending = (c.requested.w != c.active.w) || 839 (c.requested.h != c.active.h); 840 841 if (resizePending) { 842 // don't let Layer::doTransaction update the drawing state 843 // if we have a pending resize, unless we are in fixed-size mode. 844 // the drawing state will be updated only once we receive a buffer 845 // with the correct size. 846 // 847 // in particular, we want to make sure the clip (which is part 848 // of the geometry state) is latched together with the size but is 849 // latched immediately when no resizing is involved. 850 851 flags |= eDontUpdateGeometryState; 852 } 853 } 854 855 // always set active to requested, unless we're asked not to 856 // this is used by Layer, which special cases resizes. 857 if (flags & eDontUpdateGeometryState) { 858 } else { 859 Layer::State& editCurrentState(getCurrentState()); 860 editCurrentState.active = c.requested; 861 } 862 863 if (s.active != c.active) { 864 // invalidate and recompute the visible regions if needed 865 flags |= Layer::eVisibleRegion; 866 } 867 868 if (c.sequence != s.sequence) { 869 // invalidate and recompute the visible regions if needed 870 flags |= eVisibleRegion; 871 this->contentDirty = true; 872 873 // we may use linear filtering, if the matrix scales us 874 const uint8_t type = c.transform.getType(); 875 mNeedsFiltering = (!c.transform.preserveRects() || 876 (type >= Transform::SCALE)); 877 } 878 879 // Commit the transaction 880 commitTransaction(); 881 return flags; 882} 883 884void Layer::commitTransaction() { 885 mDrawingState = mCurrentState; 886} 887 888uint32_t Layer::getTransactionFlags(uint32_t flags) { 889 return android_atomic_and(~flags, &mTransactionFlags) & flags; 890} 891 892uint32_t Layer::setTransactionFlags(uint32_t flags) { 893 return android_atomic_or(flags, &mTransactionFlags); 894} 895 896bool Layer::setPosition(float x, float y) { 897 if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y) 898 return false; 899 mCurrentState.sequence++; 900 mCurrentState.transform.set(x, y); 901 setTransactionFlags(eTransactionNeeded); 902 return true; 903} 904bool Layer::setLayer(uint32_t z) { 905 if (mCurrentState.z == z) 906 return false; 907 mCurrentState.sequence++; 908 mCurrentState.z = z; 909 setTransactionFlags(eTransactionNeeded); 910 return true; 911} 912bool Layer::setSize(uint32_t w, uint32_t h) { 913 if (mCurrentState.requested.w == w && mCurrentState.requested.h == h) 914 return false; 915 mCurrentState.requested.w = w; 916 mCurrentState.requested.h = h; 917 setTransactionFlags(eTransactionNeeded); 918 return true; 919} 920bool Layer::setAlpha(uint8_t alpha) { 921 if (mCurrentState.alpha == alpha) 922 return false; 923 mCurrentState.sequence++; 924 mCurrentState.alpha = alpha; 925 setTransactionFlags(eTransactionNeeded); 926 return true; 927} 928bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) { 929 mCurrentState.sequence++; 930 mCurrentState.transform.set( 931 matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy); 932 setTransactionFlags(eTransactionNeeded); 933 return true; 934} 935bool Layer::setTransparentRegionHint(const Region& transparent) { 936 mCurrentState.requestedTransparentRegion = transparent; 937 setTransactionFlags(eTransactionNeeded); 938 return true; 939} 940bool Layer::setFlags(uint8_t flags, uint8_t mask) { 941 const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask); 942 if (mCurrentState.flags == newFlags) 943 return false; 944 mCurrentState.sequence++; 945 mCurrentState.flags = newFlags; 946 setTransactionFlags(eTransactionNeeded); 947 return true; 948} 949bool Layer::setCrop(const Rect& crop) { 950 if (mCurrentState.requested.crop == crop) 951 return false; 952 mCurrentState.sequence++; 953 mCurrentState.requested.crop = crop; 954 setTransactionFlags(eTransactionNeeded); 955 return true; 956} 957 958bool Layer::setLayerStack(uint32_t layerStack) { 959 if (mCurrentState.layerStack == layerStack) 960 return false; 961 mCurrentState.sequence++; 962 mCurrentState.layerStack = layerStack; 963 setTransactionFlags(eTransactionNeeded); 964 return true; 965} 966 967// ---------------------------------------------------------------------------- 968// pageflip handling... 969// ---------------------------------------------------------------------------- 970 971bool Layer::onPreComposition() { 972 mRefreshPending = false; 973 return mQueuedFrames > 0 || mSidebandStreamChanged; 974} 975 976void Layer::onPostComposition() { 977 if (mFrameLatencyNeeded) { 978 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp(); 979 mFrameTracker.setDesiredPresentTime(desiredPresentTime); 980 981 sp<Fence> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFence(); 982 if (frameReadyFence->isValid()) { 983 mFrameTracker.setFrameReadyFence(frameReadyFence); 984 } else { 985 // There was no fence for this frame, so assume that it was ready 986 // to be presented at the desired present time. 987 mFrameTracker.setFrameReadyTime(desiredPresentTime); 988 } 989 990 const HWComposer& hwc = mFlinger->getHwComposer(); 991 sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); 992 if (presentFence->isValid()) { 993 mFrameTracker.setActualPresentFence(presentFence); 994 } else { 995 // The HWC doesn't support present fences, so use the refresh 996 // timestamp instead. 997 nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 998 mFrameTracker.setActualPresentTime(presentTime); 999 } 1000 1001 mFrameTracker.advanceFrame(); 1002 mFrameLatencyNeeded = false; 1003 } 1004} 1005 1006bool Layer::isVisible() const { 1007 const Layer::State& s(mDrawingState); 1008 return !(s.flags & layer_state_t::eLayerHidden) && s.alpha 1009 && (mActiveBuffer != NULL || mSidebandStream != NULL); 1010} 1011 1012Region Layer::latchBuffer(bool& recomputeVisibleRegions) 1013{ 1014 ATRACE_CALL(); 1015 1016 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) { 1017 // mSidebandStreamChanged was true 1018 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream(); 1019 } 1020 1021 Region outDirtyRegion; 1022 if (mQueuedFrames > 0) { 1023 1024 // if we've already called updateTexImage() without going through 1025 // a composition step, we have to skip this layer at this point 1026 // because we cannot call updateTeximage() without a corresponding 1027 // compositionComplete() call. 1028 // we'll trigger an update in onPreComposition(). 1029 if (mRefreshPending) { 1030 return outDirtyRegion; 1031 } 1032 1033 // Capture the old state of the layer for comparisons later 1034 const State& s(getDrawingState()); 1035 const bool oldOpacity = isOpaque(s); 1036 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 1037 1038 struct Reject : public SurfaceFlingerConsumer::BufferRejecter { 1039 Layer::State& front; 1040 Layer::State& current; 1041 bool& recomputeVisibleRegions; 1042 bool stickyTransformSet; 1043 Reject(Layer::State& front, Layer::State& current, 1044 bool& recomputeVisibleRegions, bool stickySet) 1045 : front(front), current(current), 1046 recomputeVisibleRegions(recomputeVisibleRegions), 1047 stickyTransformSet(stickySet) { 1048 } 1049 1050 virtual bool reject(const sp<GraphicBuffer>& buf, 1051 const IGraphicBufferConsumer::BufferItem& item) { 1052 if (buf == NULL) { 1053 return false; 1054 } 1055 1056 uint32_t bufWidth = buf->getWidth(); 1057 uint32_t bufHeight = buf->getHeight(); 1058 1059 // check that we received a buffer of the right size 1060 // (Take the buffer's orientation into account) 1061 if (item.mTransform & Transform::ROT_90) { 1062 swap(bufWidth, bufHeight); 1063 } 1064 1065 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 1066 if (front.active != front.requested) { 1067 1068 if (isFixedSize || 1069 (bufWidth == front.requested.w && 1070 bufHeight == front.requested.h)) 1071 { 1072 // Here we pretend the transaction happened by updating the 1073 // current and drawing states. Drawing state is only accessed 1074 // in this thread, no need to have it locked 1075 front.active = front.requested; 1076 1077 // We also need to update the current state so that 1078 // we don't end-up overwriting the drawing state with 1079 // this stale current state during the next transaction 1080 // 1081 // NOTE: We don't need to hold the transaction lock here 1082 // because State::active is only accessed from this thread. 1083 current.active = front.active; 1084 1085 // recompute visible region 1086 recomputeVisibleRegions = true; 1087 } 1088 1089 ALOGD_IF(DEBUG_RESIZE, 1090 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 1091 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 1092 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 1093 bufWidth, bufHeight, item.mTransform, item.mScalingMode, 1094 front.active.w, front.active.h, 1095 front.active.crop.left, 1096 front.active.crop.top, 1097 front.active.crop.right, 1098 front.active.crop.bottom, 1099 front.active.crop.getWidth(), 1100 front.active.crop.getHeight(), 1101 front.requested.w, front.requested.h, 1102 front.requested.crop.left, 1103 front.requested.crop.top, 1104 front.requested.crop.right, 1105 front.requested.crop.bottom, 1106 front.requested.crop.getWidth(), 1107 front.requested.crop.getHeight()); 1108 } 1109 1110 if (!isFixedSize && !stickyTransformSet) { 1111 if (front.active.w != bufWidth || 1112 front.active.h != bufHeight) { 1113 // reject this buffer 1114 ALOGE("rejecting buffer: bufWidth=%d, bufHeight=%d, front.active.{w=%d, h=%d}", 1115 bufWidth, bufHeight, front.active.w, front.active.h); 1116 return true; 1117 } 1118 } 1119 1120 // if the transparent region has changed (this test is 1121 // conservative, but that's fine, worst case we're doing 1122 // a bit of extra work), we latch the new one and we 1123 // trigger a visible-region recompute. 1124 if (!front.activeTransparentRegion.isTriviallyEqual( 1125 front.requestedTransparentRegion)) { 1126 front.activeTransparentRegion = front.requestedTransparentRegion; 1127 1128 // We also need to update the current state so that 1129 // we don't end-up overwriting the drawing state with 1130 // this stale current state during the next transaction 1131 // 1132 // NOTE: We don't need to hold the transaction lock here 1133 // because State::active is only accessed from this thread. 1134 current.activeTransparentRegion = front.activeTransparentRegion; 1135 1136 // recompute visible region 1137 recomputeVisibleRegions = true; 1138 } 1139 1140 return false; 1141 } 1142 }; 1143 1144 Reject r(mDrawingState, getCurrentState(), recomputeVisibleRegions, 1145 getProducerStickyTransform() != 0); 1146 1147 status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r, 1148 mFlinger->mPrimaryDispSync); 1149 if (updateResult == BufferQueue::PRESENT_LATER) { 1150 // Producer doesn't want buffer to be displayed yet. Signal a 1151 // layer update so we check again at the next opportunity. 1152 mFlinger->signalLayerUpdate(); 1153 return outDirtyRegion; 1154 } 1155 1156 // Decrement the queued-frames count. Signal another event if we 1157 // have more frames pending. 1158 if (android_atomic_dec(&mQueuedFrames) > 1) { 1159 mFlinger->signalLayerUpdate(); 1160 } 1161 1162 if (updateResult != NO_ERROR) { 1163 // something happened! 1164 recomputeVisibleRegions = true; 1165 return outDirtyRegion; 1166 } 1167 1168 // update the active buffer 1169 mActiveBuffer = mSurfaceFlingerConsumer->getCurrentBuffer(); 1170 if (mActiveBuffer == NULL) { 1171 // this can only happen if the very first buffer was rejected. 1172 return outDirtyRegion; 1173 } 1174 1175 mRefreshPending = true; 1176 mFrameLatencyNeeded = true; 1177 if (oldActiveBuffer == NULL) { 1178 // the first time we receive a buffer, we need to trigger a 1179 // geometry invalidation. 1180 recomputeVisibleRegions = true; 1181 } 1182 1183 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop()); 1184 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform()); 1185 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode()); 1186 if ((crop != mCurrentCrop) || 1187 (transform != mCurrentTransform) || 1188 (scalingMode != mCurrentScalingMode)) 1189 { 1190 mCurrentCrop = crop; 1191 mCurrentTransform = transform; 1192 mCurrentScalingMode = scalingMode; 1193 recomputeVisibleRegions = true; 1194 } 1195 1196 if (oldActiveBuffer != NULL) { 1197 uint32_t bufWidth = mActiveBuffer->getWidth(); 1198 uint32_t bufHeight = mActiveBuffer->getHeight(); 1199 if (bufWidth != uint32_t(oldActiveBuffer->width) || 1200 bufHeight != uint32_t(oldActiveBuffer->height)) { 1201 recomputeVisibleRegions = true; 1202 } 1203 } 1204 1205 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 1206 if (oldOpacity != isOpaque(s)) { 1207 recomputeVisibleRegions = true; 1208 } 1209 1210 // FIXME: postedRegion should be dirty & bounds 1211 Region dirtyRegion(Rect(s.active.w, s.active.h)); 1212 1213 // transform the dirty region to window-manager space 1214 outDirtyRegion = (s.transform.transform(dirtyRegion)); 1215 } 1216 return outDirtyRegion; 1217} 1218 1219uint32_t Layer::getEffectiveUsage(uint32_t usage) const 1220{ 1221 // TODO: should we do something special if mSecure is set? 1222 if (mProtectedByApp) { 1223 // need a hardware-protected path to external video sink 1224 usage |= GraphicBuffer::USAGE_PROTECTED; 1225 } 1226 if (mPotentialCursor) { 1227 usage |= GraphicBuffer::USAGE_CURSOR; 1228 } 1229 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 1230 return usage; 1231} 1232 1233void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const { 1234 uint32_t orientation = 0; 1235 if (!mFlinger->mDebugDisableTransformHint) { 1236 // The transform hint is used to improve performance, but we can 1237 // only have a single transform hint, it cannot 1238 // apply to all displays. 1239 const Transform& planeTransform(hw->getTransform()); 1240 orientation = planeTransform.getOrientation(); 1241 if (orientation & Transform::ROT_INVALID) { 1242 orientation = 0; 1243 } 1244 } 1245 mSurfaceFlingerConsumer->setTransformHint(orientation); 1246} 1247 1248// ---------------------------------------------------------------------------- 1249// debugging 1250// ---------------------------------------------------------------------------- 1251 1252void Layer::dump(String8& result, Colorizer& colorizer) const 1253{ 1254 const Layer::State& s(getDrawingState()); 1255 1256 colorizer.colorize(result, Colorizer::GREEN); 1257 result.appendFormat( 1258 "+ %s %p (%s)\n", 1259 getTypeId(), this, getName().string()); 1260 colorizer.reset(result); 1261 1262 s.activeTransparentRegion.dump(result, "transparentRegion"); 1263 visibleRegion.dump(result, "visibleRegion"); 1264 sp<Client> client(mClientRef.promote()); 1265 1266 result.appendFormat( " " 1267 "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), " 1268 "isOpaque=%1d, invalidate=%1d, " 1269 "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n" 1270 " client=%p\n", 1271 s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h, 1272 s.active.crop.left, s.active.crop.top, 1273 s.active.crop.right, s.active.crop.bottom, 1274 isOpaque(s), contentDirty, 1275 s.alpha, s.flags, 1276 s.transform[0][0], s.transform[0][1], 1277 s.transform[1][0], s.transform[1][1], 1278 client.get()); 1279 1280 sp<const GraphicBuffer> buf0(mActiveBuffer); 1281 uint32_t w0=0, h0=0, s0=0, f0=0; 1282 if (buf0 != 0) { 1283 w0 = buf0->getWidth(); 1284 h0 = buf0->getHeight(); 1285 s0 = buf0->getStride(); 1286 f0 = buf0->format; 1287 } 1288 result.appendFormat( 1289 " " 1290 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 1291 " queued-frames=%d, mRefreshPending=%d\n", 1292 mFormat, w0, h0, s0,f0, 1293 mQueuedFrames, mRefreshPending); 1294 1295 if (mSurfaceFlingerConsumer != 0) { 1296 mSurfaceFlingerConsumer->dump(result, " "); 1297 } 1298} 1299 1300void Layer::dumpFrameStats(String8& result) const { 1301 mFrameTracker.dumpStats(result); 1302} 1303 1304void Layer::clearFrameStats() { 1305 mFrameTracker.clearStats(); 1306} 1307 1308void Layer::logFrameStats() { 1309 mFrameTracker.logAndResetStats(mName); 1310} 1311 1312void Layer::getFrameStats(FrameStats* outStats) const { 1313 mFrameTracker.getStats(outStats); 1314} 1315 1316// --------------------------------------------------------------------------- 1317 1318Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, 1319 const sp<Layer>& layer) 1320 : mFlinger(flinger), mLayer(layer) { 1321} 1322 1323Layer::LayerCleaner::~LayerCleaner() { 1324 // destroy client resources 1325 mFlinger->onLayerDestroyed(mLayer); 1326} 1327 1328// --------------------------------------------------------------------------- 1329}; // namespace android 1330 1331#if defined(__gl_h_) 1332#error "don't include gl/gl.h in this file" 1333#endif 1334 1335#if defined(__gl2_h_) 1336#error "don't include gl2/gl2.h in this file" 1337#endif 1338