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