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