Layer.cpp revision 29a367bb7c14c916e991a6a0028727bd06c1e16e
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 42#define DEBUG_RESIZE 0 43 44 45namespace android { 46 47template <typename T> inline T min(T a, T b) { 48 return a<b ? a : b; 49} 50 51// --------------------------------------------------------------------------- 52 53Layer::Layer(SurfaceFlinger* flinger, 54 DisplayID display, const sp<Client>& client) 55 : LayerBaseClient(flinger, display, client), 56 mTextureName(-1U), 57 mQueuedFrames(0), 58 mCurrentTransform(0), 59 mCurrentOpacity(true), 60 mFormat(PIXEL_FORMAT_NONE), 61 mGLExtensions(GLExtensions::getInstance()), 62 mOpaqueLayer(true), 63 mNeedsDithering(false), 64 mSecure(false), 65 mProtectedByApp(false), 66 mFixedSize(false) 67{ 68 mCurrentCrop.makeInvalid(); 69 glGenTextures(1, &mTextureName); 70} 71 72void Layer::destroy(RefBase const* base) { 73 mFlinger->destroyLayer(static_cast<LayerBase const*>(base)); 74} 75 76void Layer::onFirstRef() 77{ 78 LayerBaseClient::onFirstRef(); 79 setDestroyer(this); 80 81 struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { 82 FrameQueuedListener(Layer* layer) : mLayer(layer) { } 83 private: 84 wp<Layer> mLayer; 85 virtual void onFrameAvailable() { 86 sp<Layer> that(mLayer.promote()); 87 if (that != 0) { 88 that->onFrameQueued(); 89 } 90 } 91 }; 92 mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this); 93 mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); 94 mSurfaceTexture->setSynchronousMode(true); 95 mSurfaceTexture->setBufferCountServer(2); 96} 97 98Layer::~Layer() 99{ 100 glDeleteTextures(1, &mTextureName); 101} 102 103void Layer::onFrameQueued() { 104 android_atomic_inc(&mQueuedFrames); 105 mFlinger->signalEvent(); 106} 107 108// called with SurfaceFlinger::mStateLock as soon as the layer is entered 109// in the purgatory list 110void Layer::onRemoved() 111{ 112} 113 114sp<ISurface> Layer::createSurface() 115{ 116 class BSurface : public BnSurface, public LayerCleaner { 117 wp<const Layer> mOwner; 118 virtual sp<ISurfaceTexture> getSurfaceTexture() const { 119 sp<ISurfaceTexture> res; 120 sp<const Layer> that( mOwner.promote() ); 121 if (that != NULL) { 122 res = that->mSurfaceTexture; 123 } 124 return res; 125 } 126 public: 127 BSurface(const sp<SurfaceFlinger>& flinger, 128 const sp<Layer>& layer) 129 : LayerCleaner(flinger, layer), mOwner(layer) { } 130 }; 131 sp<ISurface> sur(new BSurface(mFlinger, this)); 132 return sur; 133} 134 135status_t Layer::setBuffers( uint32_t w, uint32_t h, 136 PixelFormat format, uint32_t flags) 137{ 138 // this surfaces pixel format 139 PixelFormatInfo info; 140 status_t err = getPixelFormatInfo(format, &info); 141 if (err) return err; 142 143 // the display's pixel format 144 const DisplayHardware& hw(graphicPlane(0).displayHardware()); 145 uint32_t const maxSurfaceDims = min( 146 hw.getMaxTextureSize(), hw.getMaxViewportDims()); 147 148 // never allow a surface larger than what our underlying GL implementation 149 // can handle. 150 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 151 return BAD_VALUE; 152 } 153 154 PixelFormatInfo displayInfo; 155 getPixelFormatInfo(hw.getFormat(), &displayInfo); 156 const uint32_t hwFlags = hw.getFlags(); 157 158 mFormat = format; 159 160 mSecure = (flags & ISurfaceComposer::eSecure) ? true : false; 161 mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false; 162 mOpaqueLayer = (flags & ISurfaceComposer::eOpaque); 163 mCurrentOpacity = getOpacityForFormat(format); 164 165 mSurfaceTexture->setDefaultBufferSize(w, h); 166 mSurfaceTexture->setDefaultBufferFormat(format); 167 168 // we use the red index 169 int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); 170 int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); 171 mNeedsDithering = layerRedsize > displayRedSize; 172 173 return NO_ERROR; 174} 175 176void Layer::setGeometry(hwc_layer_t* hwcl) 177{ 178 hwcl->compositionType = HWC_FRAMEBUFFER; 179 hwcl->hints = 0; 180 hwcl->flags = 0; 181 hwcl->transform = 0; 182 hwcl->blending = HWC_BLENDING_NONE; 183 184 // we can't do alpha-fade with the hwc HAL 185 const State& s(drawingState()); 186 if (s.alpha < 0xFF) { 187 hwcl->flags = HWC_SKIP_LAYER; 188 return; 189 } 190 191 /* 192 * Transformations are applied in this order: 193 * 1) buffer orientation/flip/mirror 194 * 2) state transformation (window manager) 195 * 3) layer orientation (screen orientation) 196 * (NOTE: the matrices are multiplied in reverse order) 197 */ 198 199 const Transform bufferOrientation(mCurrentTransform); 200 const Transform& stateTransform(s.transform); 201 const Transform layerOrientation(mOrientation); 202 203 const Transform tr(layerOrientation * stateTransform * bufferOrientation); 204 205 // this gives us only the "orientation" component of the transform 206 const uint32_t finalTransform = tr.getOrientation(); 207 208 // we can only handle simple transformation 209 if (finalTransform & Transform::ROT_INVALID) { 210 hwcl->flags = HWC_SKIP_LAYER; 211 return; 212 } 213 214 hwcl->transform = finalTransform; 215 216 if (!isOpaque()) { 217 hwcl->blending = mPremultipliedAlpha ? 218 HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE; 219 } 220 221 // scaling is already applied in mTransformedBounds 222 hwcl->displayFrame.left = mTransformedBounds.left; 223 hwcl->displayFrame.top = mTransformedBounds.top; 224 hwcl->displayFrame.right = mTransformedBounds.right; 225 hwcl->displayFrame.bottom = mTransformedBounds.bottom; 226 227 hwcl->visibleRegionScreen.rects = 228 reinterpret_cast<hwc_rect_t const *>( 229 visibleRegionScreen.getArray( 230 &hwcl->visibleRegionScreen.numRects)); 231} 232 233void Layer::setPerFrameData(hwc_layer_t* hwcl) { 234 const sp<GraphicBuffer>& buffer(mActiveBuffer); 235 if (buffer == NULL) { 236 // this can happen if the client never drew into this layer yet, 237 // or if we ran out of memory. In that case, don't let 238 // HWC handle it. 239 hwcl->flags |= HWC_SKIP_LAYER; 240 hwcl->handle = NULL; 241 return; 242 } 243 hwcl->handle = buffer->handle; 244 245 if (isCropped()) { 246 hwcl->sourceCrop.left = mCurrentCrop.left; 247 hwcl->sourceCrop.top = mCurrentCrop.top; 248 hwcl->sourceCrop.right = mCurrentCrop.right; 249 hwcl->sourceCrop.bottom = mCurrentCrop.bottom; 250 } else { 251 hwcl->sourceCrop.left = 0; 252 hwcl->sourceCrop.top = 0; 253 hwcl->sourceCrop.right = buffer->width; 254 hwcl->sourceCrop.bottom = buffer->height; 255 } 256} 257 258static inline uint16_t pack565(int r, int g, int b) { 259 return (r<<11)|(g<<5)|b; 260} 261void Layer::onDraw(const Region& clip) const 262{ 263 if (CC_UNLIKELY(mActiveBuffer == 0)) { 264 // the texture has not been created yet, this Layer has 265 // in fact never been drawn into. This happens frequently with 266 // SurfaceView because the WindowManager can't know when the client 267 // has drawn the first time. 268 269 // If there is nothing under us, we paint the screen in black, otherwise 270 // we just skip this update. 271 272 // figure out if there is something below us 273 Region under; 274 const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ); 275 const size_t count = drawingLayers.size(); 276 for (size_t i=0 ; i<count ; ++i) { 277 const sp<LayerBase>& layer(drawingLayers[i]); 278 if (layer.get() == static_cast<LayerBase const*>(this)) 279 break; 280 under.orSelf(layer->visibleRegionScreen); 281 } 282 // if not everything below us is covered, we plug the holes! 283 Region holes(clip.subtract(under)); 284 if (!holes.isEmpty()) { 285 clearWithOpenGL(holes, 0, 0, 0, 1); 286 } 287 return; 288 } 289 290 GLenum target = mSurfaceTexture->getCurrentTextureTarget(); 291 glBindTexture(target, mTextureName); 292 if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) { 293 // TODO: we could be more subtle with isFixedSize() 294 glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 295 glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 296 } else { 297 glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 298 glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 299 } 300 glEnable(target); 301 glMatrixMode(GL_TEXTURE); 302 glLoadMatrixf(mTextureMatrix); 303 glMatrixMode(GL_MODELVIEW); 304 305 drawWithOpenGL(clip); 306 307 glDisable(target); 308} 309 310// As documented in libhardware header, formats in the range 311// 0x100 - 0x1FF are specific to the HAL implementation, and 312// are known to have no alpha channel 313// TODO: move definition for device-specific range into 314// hardware.h, instead of using hard-coded values here. 315#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 316 317bool Layer::getOpacityForFormat(uint32_t format) 318{ 319 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 320 return true; 321 } 322 PixelFormatInfo info; 323 status_t err = getPixelFormatInfo(PixelFormat(format), &info); 324 // in case of error (unknown format), we assume no blending 325 return (err || info.h_alpha <= info.l_alpha); 326} 327 328 329bool Layer::isOpaque() const 330{ 331 // if we don't have a buffer yet, we're translucent regardless of the 332 // layer's opaque flag. 333 if (mActiveBuffer == 0) 334 return false; 335 336 // if the layer has the opaque flag, then we're always opaque, 337 // otherwise we use the current buffer's format. 338 return mOpaqueLayer || mCurrentOpacity; 339} 340 341bool Layer::isProtected() const 342{ 343 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 344 return (activeBuffer != 0) && 345 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 346} 347 348uint32_t Layer::doTransaction(uint32_t flags) 349{ 350 const Layer::State& front(drawingState()); 351 const Layer::State& temp(currentState()); 352 353 const bool sizeChanged = (front.requested_w != temp.requested_w) || 354 (front.requested_h != temp.requested_h); 355 356 if (sizeChanged) { 357 // the size changed, we need to ask our client to request a new buffer 358 LOGD_IF(DEBUG_RESIZE, 359 "resize (layer=%p), requested (%dx%d), drawing (%d,%d), " 360 "fixedSize=%d", 361 this, 362 int(temp.requested_w), int(temp.requested_h), 363 int(front.requested_w), int(front.requested_h), 364 isFixedSize()); 365 366 if (!isFixedSize()) { 367 // we're being resized and there is a freeze display request, 368 // acquire a freeze lock, so that the screen stays put 369 // until we've redrawn at the new size; this is to avoid 370 // glitches upon orientation changes. 371 if (mFlinger->hasFreezeRequest()) { 372 // if the surface is hidden, don't try to acquire the 373 // freeze lock, since hidden surfaces may never redraw 374 if (!(front.flags & ISurfaceComposer::eLayerHidden)) { 375 mFreezeLock = mFlinger->getFreezeLock(); 376 } 377 } 378 379 // this will make sure LayerBase::doTransaction doesn't update 380 // the drawing state's size 381 Layer::State& editDraw(mDrawingState); 382 editDraw.requested_w = temp.requested_w; 383 editDraw.requested_h = temp.requested_h; 384 385 // record the new size, form this point on, when the client request 386 // a buffer, it'll get the new size. 387 mSurfaceTexture->setDefaultBufferSize(temp.requested_w, temp.requested_h); 388 } 389 } 390 391 if (temp.sequence != front.sequence) { 392 if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) { 393 // this surface is now hidden, so it shouldn't hold a freeze lock 394 // (it may never redraw, which is fine if it is hidden) 395 mFreezeLock.clear(); 396 } 397 } 398 399 return LayerBase::doTransaction(flags); 400} 401 402bool Layer::isFixedSize() const { 403 Mutex::Autolock _l(mLock); 404 return mFixedSize; 405} 406 407void Layer::setFixedSize(bool fixedSize) 408{ 409 Mutex::Autolock _l(mLock); 410 mFixedSize = fixedSize; 411} 412 413bool Layer::isCropped() const { 414 return !mCurrentCrop.isEmpty(); 415} 416 417// ---------------------------------------------------------------------------- 418// pageflip handling... 419// ---------------------------------------------------------------------------- 420 421void Layer::lockPageFlip(bool& recomputeVisibleRegions) 422{ 423 if (mQueuedFrames > 0) { 424 // signal another event if we have more frames pending 425 if (android_atomic_dec(&mQueuedFrames) > 1) { 426 mFlinger->signalEvent(); 427 } 428 429 if (mSurfaceTexture->updateTexImage() < NO_ERROR) { 430 // something happened! 431 recomputeVisibleRegions = true; 432 return; 433 } 434 435 mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 436 mSurfaceTexture->getTransformMatrix(mTextureMatrix); 437 438 const Rect crop(mSurfaceTexture->getCurrentCrop()); 439 const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 440 if ((crop != mCurrentCrop) || (transform != mCurrentTransform)) { 441 mCurrentCrop = crop; 442 mCurrentTransform = transform; 443 mFlinger->invalidateHwcGeometry(); 444 } 445 446 const bool opacity(getOpacityForFormat(mActiveBuffer->format)); 447 if (opacity != mCurrentOpacity) { 448 mCurrentOpacity = opacity; 449 recomputeVisibleRegions = true; 450 } 451 452 const GLenum target(mSurfaceTexture->getCurrentTextureTarget()); 453 glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 454 glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 455 456 // update the layer size and release freeze-lock 457 const Layer::State& front(drawingState()); 458 459 // FIXME: mPostedDirtyRegion = dirty & bounds 460 mPostedDirtyRegion.set(front.w, front.h); 461 462 sp<GraphicBuffer> newFrontBuffer(mActiveBuffer); 463 if ((newFrontBuffer->getWidth() == front.requested_w && 464 newFrontBuffer->getHeight() == front.requested_h) || 465 isFixedSize()) 466 { 467 if ((front.w != front.requested_w) || 468 (front.h != front.requested_h)) 469 { 470 // Here we pretend the transaction happened by updating the 471 // current and drawing states. Drawing state is only accessed 472 // in this thread, no need to have it locked 473 Layer::State& editDraw(mDrawingState); 474 editDraw.w = editDraw.requested_w; 475 editDraw.h = editDraw.requested_h; 476 477 // We also need to update the current state so that we don't 478 // end-up doing too much work during the next transaction. 479 // NOTE: We actually don't need hold the transaction lock here 480 // because State::w and State::h are only accessed from 481 // this thread 482 Layer::State& editTemp(currentState()); 483 editTemp.w = editDraw.w; 484 editTemp.h = editDraw.h; 485 486 // recompute visible region 487 recomputeVisibleRegions = true; 488 } 489 490 // we now have the correct size, unfreeze the screen 491 mFreezeLock.clear(); 492 } 493 } 494} 495 496void Layer::unlockPageFlip( 497 const Transform& planeTransform, Region& outDirtyRegion) 498{ 499 Region dirtyRegion(mPostedDirtyRegion); 500 if (!dirtyRegion.isEmpty()) { 501 mPostedDirtyRegion.clear(); 502 // The dirty region is given in the layer's coordinate space 503 // transform the dirty region by the surface's transformation 504 // and the global transformation. 505 const Layer::State& s(drawingState()); 506 const Transform tr(planeTransform * s.transform); 507 dirtyRegion = tr.transform(dirtyRegion); 508 509 // At this point, the dirty region is in screen space. 510 // Make sure it's constrained by the visible region (which 511 // is in screen space as well). 512 dirtyRegion.andSelf(visibleRegionScreen); 513 outDirtyRegion.orSelf(dirtyRegion); 514 } 515 if (visibleRegionScreen.isEmpty()) { 516 // an invisible layer should not hold a freeze-lock 517 // (because it may never be updated and therefore never release it) 518 mFreezeLock.clear(); 519 } 520} 521 522void Layer::dump(String8& result, char* buffer, size_t SIZE) const 523{ 524 LayerBaseClient::dump(result, buffer, SIZE); 525 526 sp<const GraphicBuffer> buf0(mActiveBuffer); 527 uint32_t w0=0, h0=0, s0=0, f0=0; 528 if (buf0 != 0) { 529 w0 = buf0->getWidth(); 530 h0 = buf0->getHeight(); 531 s0 = buf0->getStride(); 532 f0 = buf0->format; 533 } 534 snprintf(buffer, SIZE, 535 " " 536 "format=%2d, activeBuffer=[%3ux%3u:%3u,%3u]," 537 " freezeLock=%p, queued-frames=%d\n", 538 mFormat, w0, h0, s0,f0, 539 getFreezeLock().get(), mQueuedFrames); 540 541 result.append(buffer); 542 543 if (mSurfaceTexture != 0) { 544 mSurfaceTexture->dump(result, " ", buffer, SIZE); 545 } 546} 547 548uint32_t Layer::getEffectiveUsage(uint32_t usage) const 549{ 550 // TODO: should we do something special if mSecure is set? 551 if (mProtectedByApp) { 552 // need a hardware-protected path to external video sink 553 usage |= GraphicBuffer::USAGE_PROTECTED; 554 } 555 return usage; 556} 557 558// --------------------------------------------------------------------------- 559 560 561}; // namespace android 562