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