Layer.cpp revision 8aedd4737d6ce8548d2fd5def65b1e1737283821
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#include <stdlib.h> 18#include <stdint.h> 19#include <sys/types.h> 20 21#include <cutils/compiler.h> 22#include <cutils/native_handle.h> 23#include <cutils/properties.h> 24 25#include <utils/Errors.h> 26#include <utils/Log.h> 27#include <utils/StopWatch.h> 28 29#include <ui/GraphicBuffer.h> 30#include <ui/PixelFormat.h> 31 32#include <surfaceflinger/Surface.h> 33 34#include "clz.h" 35#include "DisplayHardware/DisplayHardware.h" 36#include "DisplayHardware/HWComposer.h" 37#include "GLExtensions.h" 38#include "Layer.h" 39#include "SurfaceFlinger.h" 40#include "SurfaceTextureLayer.h" 41#include <math.h> 42 43#define DEBUG_RESIZE 0 44 45 46namespace android { 47 48// --------------------------------------------------------------------------- 49 50Layer::Layer(SurfaceFlinger* flinger, 51 DisplayID display, const sp<Client>& client) 52 : LayerBaseClient(flinger, display, client), 53 mTextureName(-1U), 54 mQueuedFrames(0), 55 mCurrentTransform(0), 56 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 57 mCurrentOpacity(true), 58 mFrameLatencyNeeded(false), 59 mFrameLatencyOffset(0), 60 mFormat(PIXEL_FORMAT_NONE), 61 mGLExtensions(GLExtensions::getInstance()), 62 mOpaqueLayer(true), 63 mNeedsDithering(false), 64 mSecure(false), 65 mProtectedByApp(false) 66{ 67 mCurrentCrop.makeInvalid(); 68 glGenTextures(1, &mTextureName); 69} 70 71void Layer::onLayerDisplayed() { 72 if (mFrameLatencyNeeded) { 73 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 74 mFrameStats[mFrameLatencyOffset].timestamp = mSurfaceTexture->getTimestamp(); 75 mFrameStats[mFrameLatencyOffset].set = systemTime(); 76 mFrameStats[mFrameLatencyOffset].vsync = hw.getRefreshTimestamp(); 77 mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; 78 mFrameLatencyNeeded = false; 79 } 80} 81 82void Layer::onFirstRef() 83{ 84 LayerBaseClient::onFirstRef(); 85 86 struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { 87 FrameQueuedListener(Layer* layer) : mLayer(layer) { } 88 private: 89 wp<Layer> mLayer; 90 virtual void onFrameAvailable() { 91 sp<Layer> that(mLayer.promote()); 92 if (that != 0) { 93 that->onFrameQueued(); 94 } 95 } 96 }; 97 mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this); 98 mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); 99 mSurfaceTexture->setSynchronousMode(true); 100#ifdef USE_TRIPLE_BUFFERING 101#warning "using triple buffering" 102 mSurfaceTexture->setBufferCountServer(3); 103#else 104 mSurfaceTexture->setBufferCountServer(2); 105#endif 106} 107 108Layer::~Layer() 109{ 110 mFlinger->postMessageAsync( 111 new SurfaceFlinger::MessageDestroyGLTexture(mTextureName) ); 112} 113 114void Layer::onFrameQueued() { 115 android_atomic_inc(&mQueuedFrames); 116 mFlinger->signalEvent(); 117} 118 119// called with SurfaceFlinger::mStateLock as soon as the layer is entered 120// in the purgatory list 121void Layer::onRemoved() 122{ 123 mSurfaceTexture->abandon(); 124} 125 126void Layer::setName(const String8& name) { 127 LayerBase::setName(name); 128 mSurfaceTexture->setName(name); 129} 130 131sp<ISurface> Layer::createSurface() 132{ 133 class BSurface : public BnSurface, public LayerCleaner { 134 wp<const Layer> mOwner; 135 virtual sp<ISurfaceTexture> getSurfaceTexture() const { 136 sp<ISurfaceTexture> res; 137 sp<const Layer> that( mOwner.promote() ); 138 if (that != NULL) { 139 res = that->mSurfaceTexture; 140 } 141 return res; 142 } 143 public: 144 BSurface(const sp<SurfaceFlinger>& flinger, 145 const sp<Layer>& layer) 146 : LayerCleaner(flinger, layer), mOwner(layer) { } 147 }; 148 sp<ISurface> sur(new BSurface(mFlinger, this)); 149 return sur; 150} 151 152wp<IBinder> Layer::getSurfaceTextureBinder() const 153{ 154 return mSurfaceTexture->asBinder(); 155} 156 157status_t Layer::setBuffers( uint32_t w, uint32_t h, 158 PixelFormat format, uint32_t flags) 159{ 160 // this surfaces pixel format 161 PixelFormatInfo info; 162 status_t err = getPixelFormatInfo(format, &info); 163 if (err) return err; 164 165 // the display's pixel format 166 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 167 uint32_t const maxSurfaceDims = min( 168 hw.getMaxTextureSize(), hw.getMaxViewportDims()); 169 170 // never allow a surface larger than what our underlying GL implementation 171 // can handle. 172 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 173 return BAD_VALUE; 174 } 175 176 PixelFormatInfo displayInfo; 177 getPixelFormatInfo(hw.getFormat(), &displayInfo); 178 const uint32_t hwFlags = hw.getFlags(); 179 180 mFormat = format; 181 182 mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 183 mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; 184 mOpaqueLayer = (flags & ISurfaceComposer::eOpaque); 185 mCurrentOpacity = getOpacityForFormat(format); 186 187 mSurfaceTexture->setDefaultBufferSize(w, h); 188 mSurfaceTexture->setDefaultBufferFormat(format); 189 190 // we use the red index 191 int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 192 int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 193 mNeedsDithering = layerRedsize > displayRedSize; 194 195 return NO_ERROR; 196} 197 198void Layer::setGeometry(hwc_layer_t* hwcl) 199{ 200 LayerBaseClient::setGeometry(hwcl); 201 202 hwcl->flags &= ~HWC_SKIP_LAYER; 203 204 // we can't do alpha-fade with the hwc HAL 205 const State& s(drawingState()); 206 if (s.alpha < 0xFF) { 207 hwcl->flags = HWC_SKIP_LAYER; 208 } 209 210 /* 211 * Transformations are applied in this order: 212 * 1) buffer orientation/flip/mirror 213 * 2) state transformation (window manager) 214 * 3) layer orientation (screen orientation) 215 * mTransform is already the composition of (2) and (3) 216 * (NOTE: the matrices are multiplied in reverse order) 217 */ 218 219 const Transform bufferOrientation(mCurrentTransform); 220 const Transform tr(mTransform * bufferOrientation); 221 222 // this gives us only the "orientation" component of the transform 223 const uint32_t finalTransform = tr.getOrientation(); 224 225 // we can only handle simple transformation 226 if (finalTransform & Transform::ROT_INVALID) { 227 hwcl->flags = HWC_SKIP_LAYER; 228 } else { 229 hwcl->transform = finalTransform; 230 } 231 232 if (isCropped()) { 233 hwcl->sourceCrop.left = mCurrentCrop.left; 234 hwcl->sourceCrop.top = mCurrentCrop.top; 235 hwcl->sourceCrop.right = mCurrentCrop.right; 236 hwcl->sourceCrop.bottom = mCurrentCrop.bottom; 237 } else { 238 const sp<GraphicBuffer>& buffer(mActiveBuffer); 239 hwcl->sourceCrop.left = 0; 240 hwcl->sourceCrop.top = 0; 241 if (buffer != NULL) { 242 hwcl->sourceCrop.right = buffer->width; 243 hwcl->sourceCrop.bottom = buffer->height; 244 } else { 245 hwcl->sourceCrop.right = mTransformedBounds.width(); 246 hwcl->sourceCrop.bottom = mTransformedBounds.height(); 247 } 248 } 249} 250 251void Layer::setPerFrameData(hwc_layer_t* hwcl) { 252 const sp<GraphicBuffer>& buffer(mActiveBuffer); 253 if (buffer == NULL) { 254 // this can happen if the client never drew into this layer yet, 255 // or if we ran out of memory. In that case, don't let 256 // HWC handle it. 257 hwcl->flags |= HWC_SKIP_LAYER; 258 hwcl->handle = NULL; 259 } else { 260 hwcl->handle = buffer->handle; 261 } 262} 263 264void Layer::onDraw(const Region& clip) const 265{ 266 if (CC_UNLIKELY(mActiveBuffer == 0)) { 267 // the texture has not been created yet, this Layer has 268 // in fact never been drawn into. This happens frequently with 269 // SurfaceView because the WindowManager can't know when the client 270 // has drawn the first time. 271 272 // If there is nothing under us, we paint the screen in black, otherwise 273 // we just skip this update. 274 275 // figure out if there is something below us 276 Region under; 277 const SurfaceFlinger::LayerVector& drawingLayers( 278 mFlinger->mDrawingState.layersSortedByZ); 279 const size_t count = drawingLayers.size(); 280 for (size_t i=0 ; i<count ; ++i) { 281 const sp<LayerBase>& layer(drawingLayers[i]); 282 if (layer.get() == static_cast<LayerBase const*>(this)) 283 break; 284 under.orSelf(layer->visibleRegionScreen); 285 } 286 // if not everything below us is covered, we plug the holes! 287 Region holes(clip.subtract(under)); 288 if (!holes.isEmpty()) { 289 clearWithOpenGL(holes, 0, 0, 0, 1); 290 } 291 return; 292 } 293 294 if (!isProtected()) { 295 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 296 GLenum filter = GL_NEAREST; 297 if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) { 298 // TODO: we could be more subtle with isFixedSize() 299 filter = GL_LINEAR; 300 } 301 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 302 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 303 glMatrixMode(GL_TEXTURE); 304 glLoadMatrixf(mTextureMatrix); 305 glMatrixMode(GL_MODELVIEW); 306 glDisable(GL_TEXTURE_2D); 307 glEnable(GL_TEXTURE_EXTERNAL_OES); 308 } else { 309 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 310 glMatrixMode(GL_TEXTURE); 311 glLoadIdentity(); 312 glMatrixMode(GL_MODELVIEW); 313 glDisable(GL_TEXTURE_EXTERNAL_OES); 314 glEnable(GL_TEXTURE_2D); 315 } 316 317 drawWithOpenGL(clip); 318 319 glDisable(GL_TEXTURE_EXTERNAL_OES); 320 glDisable(GL_TEXTURE_2D); 321} 322 323// As documented in libhardware header, formats in the range 324// 0x100 - 0x1FF are specific to the HAL implementation, and 325// are known to have no alpha channel 326// TODO: move definition for device-specific range into 327// hardware.h, instead of using hard-coded values here. 328#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 329 330bool Layer::getOpacityForFormat(uint32_t format) 331{ 332 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 333 return true; 334 } 335 PixelFormatInfo info; 336 status_t err = getPixelFormatInfo(PixelFormat(format), &info); 337 // in case of error (unknown format), we assume no blending 338 return (err || info.h_alpha <= info.l_alpha); 339} 340 341 342bool Layer::isOpaque() const 343{ 344 // if we don't have a buffer yet, we're translucent regardless of the 345 // layer's opaque flag. 346 if (mActiveBuffer == 0) { 347 return false; 348 } 349 350 // if the layer has the opaque flag, then we're always opaque, 351 // otherwise we use the current buffer's format. 352 return mOpaqueLayer || mCurrentOpacity; 353} 354 355bool Layer::isProtected() const 356{ 357 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 358 return (activeBuffer != 0) && 359 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 360} 361 362uint32_t Layer::doTransaction(uint32_t flags) 363{ 364 const Layer::State& front(drawingState()); 365 const Layer::State& temp(currentState()); 366 367 const bool sizeChanged = (front.requested_w != temp.requested_w) || 368 (front.requested_h != temp.requested_h); 369 370 if (sizeChanged) { 371 // the size changed, we need to ask our client to request a new buffer 372 ALOGD_IF(DEBUG_RESIZE, 373 "doTransaction: " 374 "resize (layer=%p), requested (%dx%d), drawing (%d,%d), " 375 "scalingMode=%d", 376 this, 377 int(temp.requested_w), int(temp.requested_h), 378 int(front.requested_w), int(front.requested_h), 379 mCurrentScalingMode); 380 381 if (!isFixedSize()) { 382 // this will make sure LayerBase::doTransaction doesn't update 383 // the drawing state's size 384 Layer::State& editDraw(mDrawingState); 385 editDraw.requested_w = temp.requested_w; 386 editDraw.requested_h = temp.requested_h; 387 } 388 389 // record the new size, form this point on, when the client request 390 // a buffer, it'll get the new size. 391 mSurfaceTexture->setDefaultBufferSize(temp.requested_w, 392 temp.requested_h); 393 } 394 395 return LayerBase::doTransaction(flags); 396} 397 398bool Layer::isFixedSize() const { 399 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 400} 401 402bool Layer::isCropped() const { 403 return !mCurrentCrop.isEmpty(); 404} 405 406// ---------------------------------------------------------------------------- 407// pageflip handling... 408// ---------------------------------------------------------------------------- 409 410void Layer::lockPageFlip(bool& recomputeVisibleRegions) 411{ 412 if (mQueuedFrames > 0) { 413 // Capture the old state of the layer for comparisons later 414 const bool oldOpacity = isOpaque(); 415 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 416 417 // signal another event if we have more frames pending 418 if (android_atomic_dec(&mQueuedFrames) > 1) { 419 mFlinger->signalEvent(); 420 } 421 422 if (mSurfaceTexture->updateTexImage() < NO_ERROR) { 423 // something happened! 424 recomputeVisibleRegions = true; 425 return; 426 } 427 428 // update the active buffer 429 mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 430 mFrameLatencyNeeded = true; 431 432 const Rect crop(mSurfaceTexture->getCurrentCrop()); 433 const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 434 const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); 435 if ((crop != mCurrentCrop) || 436 (transform != mCurrentTransform) || 437 (scalingMode != mCurrentScalingMode)) 438 { 439 mCurrentCrop = crop; 440 mCurrentTransform = transform; 441 mCurrentScalingMode = scalingMode; 442 mFlinger->invalidateHwcGeometry(); 443 } 444 445 GLfloat textureMatrix[16]; 446 mSurfaceTexture->getTransformMatrix(textureMatrix); 447 if (memcmp(textureMatrix, mTextureMatrix, sizeof(textureMatrix))) { 448 memcpy(mTextureMatrix, textureMatrix, sizeof(textureMatrix)); 449 mFlinger->invalidateHwcGeometry(); 450 } 451 452 uint32_t bufWidth = mActiveBuffer->getWidth(); 453 uint32_t bufHeight = mActiveBuffer->getHeight(); 454 if (oldActiveBuffer != NULL) { 455 if (bufWidth != uint32_t(oldActiveBuffer->width) || 456 bufHeight != uint32_t(oldActiveBuffer->height)) { 457 mFlinger->invalidateHwcGeometry(); 458 } 459 } 460 461 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 462 if (oldOpacity != isOpaque()) { 463 recomputeVisibleRegions = true; 464 } 465 466 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 467 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 468 469 // update the layer size if needed 470 const Layer::State& front(drawingState()); 471 472 // FIXME: mPostedDirtyRegion = dirty & bounds 473 mPostedDirtyRegion.set(front.w, front.h); 474 475 if ((front.w != front.requested_w) || 476 (front.h != front.requested_h)) 477 { 478 // check that we received a buffer of the right size 479 // (Take the buffer's orientation into account) 480 if (mCurrentTransform & Transform::ROT_90) { 481 swap(bufWidth, bufHeight); 482 } 483 484 if (isFixedSize() || 485 (bufWidth == front.requested_w && 486 bufHeight == front.requested_h)) 487 { 488 // Here we pretend the transaction happened by updating the 489 // current and drawing states. Drawing state is only accessed 490 // in this thread, no need to have it locked 491 Layer::State& editDraw(mDrawingState); 492 editDraw.w = editDraw.requested_w; 493 editDraw.h = editDraw.requested_h; 494 495 // We also need to update the current state so that we don't 496 // end-up doing too much work during the next transaction. 497 // NOTE: We actually don't need hold the transaction lock here 498 // because State::w and State::h are only accessed from 499 // this thread 500 Layer::State& editTemp(currentState()); 501 editTemp.w = editDraw.w; 502 editTemp.h = editDraw.h; 503 504 // recompute visible region 505 recomputeVisibleRegions = true; 506 } 507 508 ALOGD_IF(DEBUG_RESIZE, 509 "lockPageFlip : " 510 " (layer=%p), buffer (%ux%u, tr=%02x), " 511 "requested (%dx%d)", 512 this, 513 bufWidth, bufHeight, mCurrentTransform, 514 front.requested_w, front.requested_h); 515 } 516 } 517} 518 519void Layer::unlockPageFlip( 520 const Transform& planeTransform, Region& outDirtyRegion) 521{ 522 Region dirtyRegion(mPostedDirtyRegion); 523 if (!dirtyRegion.isEmpty()) { 524 mPostedDirtyRegion.clear(); 525 // The dirty region is given in the layer's coordinate space 526 // transform the dirty region by the surface's transformation 527 // and the global transformation. 528 const Layer::State& s(drawingState()); 529 const Transform tr(planeTransform * s.transform); 530 dirtyRegion = tr.transform(dirtyRegion); 531 532 // At this point, the dirty region is in screen space. 533 // Make sure it's constrained by the visible region (which 534 // is in screen space as well). 535 dirtyRegion.andSelf(visibleRegionScreen); 536 outDirtyRegion.orSelf(dirtyRegion); 537 } 538} 539 540void Layer::dump(String8& result, char* buffer, size_t SIZE) const 541{ 542 LayerBaseClient::dump(result, buffer, SIZE); 543 544 sp<const GraphicBuffer> buf0(mActiveBuffer); 545 uint32_t w0=0, h0=0, s0=0, f0=0; 546 if (buf0 != 0) { 547 w0 = buf0->getWidth(); 548 h0 = buf0->getHeight(); 549 s0 = buf0->getStride(); 550 f0 = buf0->format; 551 } 552 snprintf(buffer, SIZE, 553 " " 554 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 555 " transform-hint=0x%02x, queued-frames=%d\n", 556 mFormat, w0, h0, s0,f0, 557 getTransformHint(), mQueuedFrames); 558 559 result.append(buffer); 560 561 if (mSurfaceTexture != 0) { 562 mSurfaceTexture->dump(result, " ", buffer, SIZE); 563 } 564} 565 566void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 567{ 568 LayerBaseClient::dumpStats(result, buffer, SIZE); 569 const size_t o = mFrameLatencyOffset; 570 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 571 const nsecs_t period = hw.getRefreshPeriod(); 572 result.appendFormat("%lld\n", period); 573 for (size_t i=0 ; i<128 ; i++) { 574 const size_t index = (o+i) % 128; 575 const nsecs_t time_app = mFrameStats[index].timestamp; 576 const nsecs_t time_set = mFrameStats[index].set; 577 const nsecs_t time_vsync = mFrameStats[index].vsync; 578 result.appendFormat("%lld\t%lld\t%lld\n", 579 time_app, 580 time_vsync, 581 time_set); 582 } 583 result.append("\n"); 584} 585 586void Layer::clearStats() 587{ 588 LayerBaseClient::clearStats(); 589 memset(mFrameStats, 0, sizeof(mFrameStats)); 590} 591 592uint32_t Layer::getEffectiveUsage(uint32_t usage) const 593{ 594 // TODO: should we do something special if mSecure is set? 595 if (mProtectedByApp) { 596 // need a hardware-protected path to external video sink 597 usage |= GraphicBuffer::USAGE_PROTECTED; 598 } 599 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 600 return usage; 601} 602 603uint32_t Layer::getTransformHint() const { 604 uint32_t orientation = 0; 605 if (!mFlinger->mDebugDisableTransformHint) { 606 orientation = getPlaneOrientation(); 607 if (orientation & Transform::ROT_INVALID) { 608 orientation = 0; 609 } 610 } 611 return orientation; 612} 613 614// --------------------------------------------------------------------------- 615 616 617}; // namespace android 618