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