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