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