Layer.cpp revision 6905205c8d130b6ea3a813c1b9283492ed183367
15b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org/* 25b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * Copyright (C) 2007 The Android Open Source Project 35b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * 45b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * Licensed under the Apache License, Version 2.0 (the "License"); 55b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * you may not use this file except in compliance with the License. 65b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * You may obtain a copy of the License at 75b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * 85b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * http://www.apache.org/licenses/LICENSE-2.0 95b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * 105b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * Unless required by applicable law or agreed to in writing, software 115b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * distributed under the License is distributed on an "AS IS" BASIS, 125b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * See the License for the specific language governing permissions and 145b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org * limitations under the License. 155b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org */ 165b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 175b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#define ATRACE_TAG ATRACE_TAG_GRAPHICS 185b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 195b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <stdlib.h> 205b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <stdint.h> 215b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <sys/types.h> 225b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <math.h> 235b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 245b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <cutils/compiler.h> 255b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <cutils/native_handle.h> 265b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <cutils/properties.h> 275b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 285b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <utils/Errors.h> 295b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <utils/Log.h> 305b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <utils/StopWatch.h> 315b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <utils/Trace.h> 325b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 335b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <ui/GraphicBuffer.h> 345b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <ui/PixelFormat.h> 355b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 365b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org#include <gui/Surface.h> 375b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org 38#include "clz.h" 39#include "DisplayDevice.h" 40#include "GLExtensions.h" 41#include "Layer.h" 42#include "SurfaceFlinger.h" 43#include "SurfaceTextureLayer.h" 44 45#include "DisplayHardware/HWComposer.h" 46 47#define DEBUG_RESIZE 0 48 49namespace android { 50 51// --------------------------------------------------------------------------- 52 53Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client) 54 : LayerBaseClient(flinger, client), 55 mTextureName(-1U), 56 mQueuedFrames(0), 57 mCurrentTransform(0), 58 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 59 mCurrentOpacity(true), 60 mRefreshPending(false), 61 mFrameLatencyNeeded(false), 62 mFrameLatencyOffset(0), 63 mFormat(PIXEL_FORMAT_NONE), 64 mGLExtensions(GLExtensions::getInstance()), 65 mOpaqueLayer(true), 66 mSecure(false), 67 mProtectedByApp(false) 68{ 69 mCurrentCrop.makeInvalid(); 70 glGenTextures(1, &mTextureName); 71} 72 73void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw, 74 HWComposer::HWCLayerInterface* layer) { 75 LayerBaseClient::onLayerDisplayed(hw, layer); 76 if (layer) { 77 mSurfaceTexture->setReleaseFence(layer->getAndResetReleaseFenceFd()); 78 } 79} 80 81void Layer::onFirstRef() 82{ 83 LayerBaseClient::onFirstRef(); 84 85 struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener { 86 FrameQueuedListener(Layer* layer) : mLayer(layer) { } 87 private: 88 wp<Layer> mLayer; 89 virtual void onFrameAvailable() { 90 sp<Layer> that(mLayer.promote()); 91 if (that != 0) { 92 that->onFrameQueued(); 93 } 94 } 95 }; 96 97 // Creates a custom BufferQueue for SurfaceTexture to use 98 sp<BufferQueue> bq = new SurfaceTextureLayer(); 99 mSurfaceTexture = new SurfaceTexture(mTextureName, true, 100 GL_TEXTURE_EXTERNAL_OES, false, bq); 101 102 mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 103 mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this)); 104 mSurfaceTexture->setSynchronousMode(true); 105 106#ifdef TARGET_DISABLE_TRIPLE_BUFFERING 107#warning "disabling triple buffering" 108 mSurfaceTexture->setDefaultMaxBufferCount(2); 109#else 110 mSurfaceTexture->setDefaultMaxBufferCount(3); 111#endif 112 113 updateTransformHint(); 114} 115 116Layer::~Layer() 117{ 118 mFlinger->deleteTextureAsync(mTextureName); 119} 120 121void Layer::onFrameQueued() { 122 android_atomic_inc(&mQueuedFrames); 123 mFlinger->signalLayerUpdate(); 124} 125 126// called with SurfaceFlinger::mStateLock as soon as the layer is entered 127// in the purgatory list 128void Layer::onRemoved() 129{ 130 mSurfaceTexture->abandon(); 131} 132 133void Layer::setName(const String8& name) { 134 LayerBase::setName(name); 135 mSurfaceTexture->setName(name); 136} 137 138sp<ISurface> Layer::createSurface() 139{ 140 class BSurface : public BnSurface, public LayerCleaner { 141 wp<const Layer> mOwner; 142 virtual sp<ISurfaceTexture> getSurfaceTexture() const { 143 sp<ISurfaceTexture> res; 144 sp<const Layer> that( mOwner.promote() ); 145 if (that != NULL) { 146 res = that->mSurfaceTexture->getBufferQueue(); 147 } 148 return res; 149 } 150 public: 151 BSurface(const sp<SurfaceFlinger>& flinger, 152 const sp<Layer>& layer) 153 : LayerCleaner(flinger, layer), mOwner(layer) { } 154 }; 155 sp<ISurface> sur(new BSurface(mFlinger, this)); 156 return sur; 157} 158 159wp<IBinder> Layer::getSurfaceTextureBinder() const 160{ 161 return mSurfaceTexture->getBufferQueue()->asBinder(); 162} 163 164status_t Layer::setBuffers( uint32_t w, uint32_t h, 165 PixelFormat format, uint32_t flags) 166{ 167 // this surfaces pixel format 168 PixelFormatInfo info; 169 status_t err = getPixelFormatInfo(format, &info); 170 if (err) { 171 ALOGE("unsupported pixelformat %d", format); 172 return err; 173 } 174 175 uint32_t const maxSurfaceDims = min( 176 mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); 177 178 // never allow a surface larger than what our underlying GL implementation 179 // can handle. 180 if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) { 181 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h)); 182 return BAD_VALUE; 183 } 184 185 mFormat = format; 186 187 mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false; 188 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false; 189 mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque); 190 mCurrentOpacity = getOpacityForFormat(format); 191 192 mSurfaceTexture->setDefaultBufferSize(w, h); 193 mSurfaceTexture->setDefaultBufferFormat(format); 194 mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); 195 196 return NO_ERROR; 197} 198 199Rect Layer::computeBufferCrop() const { 200 // Start with the SurfaceTexture's buffer crop... 201 Rect crop; 202 if (!mCurrentCrop.isEmpty()) { 203 crop = mCurrentCrop; 204 } else if (mActiveBuffer != NULL){ 205 crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight()); 206 } else { 207 crop.makeInvalid(); 208 return crop; 209 } 210 211 // ... then reduce that in the same proportions as the window crop reduces 212 // the window size. 213 const State& s(drawingState()); 214 if (!s.active.crop.isEmpty()) { 215 // Transform the window crop to match the buffer coordinate system, 216 // which means using the inverse of the current transform set on the 217 // SurfaceTexture. 218 uint32_t invTransform = mCurrentTransform; 219 int winWidth = s.active.w; 220 int winHeight = s.active.h; 221 if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) { 222 invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V | 223 NATIVE_WINDOW_TRANSFORM_FLIP_H; 224 winWidth = s.active.h; 225 winHeight = s.active.w; 226 } 227 Rect winCrop = s.active.crop.transform(invTransform, 228 s.active.w, s.active.h); 229 230 float xScale = float(crop.width()) / float(winWidth); 231 float yScale = float(crop.height()) / float(winHeight); 232 crop.left += int(ceilf(float(winCrop.left) * xScale)); 233 crop.top += int(ceilf(float(winCrop.top) * yScale)); 234 crop.right -= int(ceilf(float(winWidth - winCrop.right) * xScale)); 235 crop.bottom -= int(ceilf(float(winHeight - winCrop.bottom) * yScale)); 236 } 237 238 return crop; 239} 240 241void Layer::setGeometry( 242 const sp<const DisplayDevice>& hw, 243 HWComposer::HWCLayerInterface& layer) 244{ 245 LayerBaseClient::setGeometry(hw, layer); 246 247 // enable this layer 248 layer.setSkip(false); 249 250 // we can't do alpha-fade with the hwc HAL 251 const State& s(drawingState()); 252 if (s.alpha < 0xFF) { 253 layer.setSkip(true); 254 } 255 256 /* 257 * Transformations are applied in this order: 258 * 1) buffer orientation/flip/mirror 259 * 2) state transformation (window manager) 260 * 3) layer orientation (screen orientation) 261 * (NOTE: the matrices are multiplied in reverse order) 262 */ 263 264 const Transform bufferOrientation(mCurrentTransform); 265 const Transform tr(hw->getTransform() * s.transform * bufferOrientation); 266 267 // this gives us only the "orientation" component of the transform 268 const uint32_t finalTransform = tr.getOrientation(); 269 270 // we can only handle simple transformation 271 if (finalTransform & Transform::ROT_INVALID) { 272 layer.setSkip(true); 273 } else { 274 layer.setTransform(finalTransform); 275 } 276 layer.setCrop(computeBufferCrop()); 277} 278 279void Layer::setPerFrameData(const sp<const DisplayDevice>& hw, 280 HWComposer::HWCLayerInterface& layer) { 281 LayerBaseClient::setPerFrameData(hw, layer); 282 // NOTE: buffer can be NULL if the client never drew into this 283 // layer yet, or if we ran out of memory 284 layer.setBuffer(mActiveBuffer); 285} 286 287void Layer::setAcquireFence(const sp<const DisplayDevice>& hw, 288 HWComposer::HWCLayerInterface& layer) { 289 int fenceFd = -1; 290 291 // TODO: there is a possible optimization here: we only need to set the 292 // acquire fence the first time a new buffer is acquired on EACH display. 293 294 if (layer.getCompositionType() == HWC_OVERLAY) { 295 sp<Fence> fence = mSurfaceTexture->getCurrentFence(); 296 if (fence.get()) { 297 fenceFd = fence->dup(); 298 if (fenceFd == -1) { 299 ALOGW("failed to dup layer fence, skipping sync: %d", errno); 300 } 301 } 302 } 303 layer.setAcquireFenceFd(fenceFd); 304} 305 306void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const 307{ 308 ATRACE_CALL(); 309 310 if (CC_UNLIKELY(mActiveBuffer == 0)) { 311 // the texture has not been created yet, this Layer has 312 // in fact never been drawn into. This happens frequently with 313 // SurfaceView because the WindowManager can't know when the client 314 // has drawn the first time. 315 316 // If there is nothing under us, we paint the screen in black, otherwise 317 // we just skip this update. 318 319 // figure out if there is something below us 320 Region under; 321 const SurfaceFlinger::LayerVector& drawingLayers( 322 mFlinger->mDrawingState.layersSortedByZ); 323 const size_t count = drawingLayers.size(); 324 for (size_t i=0 ; i<count ; ++i) { 325 const sp<LayerBase>& layer(drawingLayers[i]); 326 if (layer.get() == static_cast<LayerBase const*>(this)) 327 break; 328 under.orSelf( hw->getTransform().transform(layer->visibleRegion) ); 329 } 330 // if not everything below us is covered, we plug the holes! 331 Region holes(clip.subtract(under)); 332 if (!holes.isEmpty()) { 333 clearWithOpenGL(hw, holes, 0, 0, 0, 1); 334 } 335 return; 336 } 337 338 status_t err = mSurfaceTexture->doGLFenceWait(); 339 if (err != OK) { 340 ALOGE("onDraw: failed waiting for fence: %d", err); 341 // Go ahead and draw the buffer anyway; no matter what we do the screen 342 // is probably going to have something visibly wrong. 343 } 344 345 if (!isProtected()) { 346 // TODO: we could be more subtle with isFixedSize() 347 const bool useFiltering = getFiltering() || needsFiltering() || isFixedSize(); 348 349 // Query the texture matrix given our current filtering mode. 350 float textureMatrix[16]; 351 mSurfaceTexture->setFilteringEnabled(useFiltering); 352 mSurfaceTexture->getTransformMatrix(textureMatrix); 353 354 // Set things up for texturing. 355 glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName); 356 GLenum filter = GL_NEAREST; 357 if (useFiltering) { 358 filter = GL_LINEAR; 359 } 360 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter); 361 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter); 362 glMatrixMode(GL_TEXTURE); 363 glLoadMatrixf(textureMatrix); 364 glMatrixMode(GL_MODELVIEW); 365 glDisable(GL_TEXTURE_2D); 366 glEnable(GL_TEXTURE_EXTERNAL_OES); 367 } else { 368 glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName()); 369 glMatrixMode(GL_TEXTURE); 370 glLoadIdentity(); 371 glMatrixMode(GL_MODELVIEW); 372 glDisable(GL_TEXTURE_EXTERNAL_OES); 373 glEnable(GL_TEXTURE_2D); 374 } 375 376 drawWithOpenGL(hw, clip); 377 378 glDisable(GL_TEXTURE_EXTERNAL_OES); 379 glDisable(GL_TEXTURE_2D); 380} 381 382// As documented in libhardware header, formats in the range 383// 0x100 - 0x1FF are specific to the HAL implementation, and 384// are known to have no alpha channel 385// TODO: move definition for device-specific range into 386// hardware.h, instead of using hard-coded values here. 387#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF) 388 389bool Layer::getOpacityForFormat(uint32_t format) 390{ 391 if (HARDWARE_IS_DEVICE_FORMAT(format)) { 392 return true; 393 } 394 PixelFormatInfo info; 395 status_t err = getPixelFormatInfo(PixelFormat(format), &info); 396 // in case of error (unknown format), we assume no blending 397 return (err || info.h_alpha <= info.l_alpha); 398} 399 400 401bool Layer::isOpaque() const 402{ 403 // if we don't have a buffer yet, we're translucent regardless of the 404 // layer's opaque flag. 405 if (mActiveBuffer == 0) { 406 return false; 407 } 408 409 // if the layer has the opaque flag, then we're always opaque, 410 // otherwise we use the current buffer's format. 411 return mOpaqueLayer || mCurrentOpacity; 412} 413 414bool Layer::isProtected() const 415{ 416 const sp<GraphicBuffer>& activeBuffer(mActiveBuffer); 417 return (activeBuffer != 0) && 418 (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); 419} 420 421uint32_t Layer::doTransaction(uint32_t flags) 422{ 423 ATRACE_CALL(); 424 425 const Layer::State& front(drawingState()); 426 const Layer::State& temp(currentState()); 427 428 const bool sizeChanged = (temp.requested.w != front.requested.w) || 429 (temp.requested.h != front.requested.h); 430 431 if (sizeChanged) { 432 // the size changed, we need to ask our client to request a new buffer 433 ALOGD_IF(DEBUG_RESIZE, 434 "doTransaction: geometry (layer=%p '%s'), tr=%02x, scalingMode=%d\n" 435 " current={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 436 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n" 437 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 438 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 439 this, (const char*) getName(), mCurrentTransform, mCurrentScalingMode, 440 temp.active.w, temp.active.h, 441 temp.active.crop.left, 442 temp.active.crop.top, 443 temp.active.crop.right, 444 temp.active.crop.bottom, 445 temp.active.crop.getWidth(), 446 temp.active.crop.getHeight(), 447 temp.requested.w, temp.requested.h, 448 temp.requested.crop.left, 449 temp.requested.crop.top, 450 temp.requested.crop.right, 451 temp.requested.crop.bottom, 452 temp.requested.crop.getWidth(), 453 temp.requested.crop.getHeight(), 454 front.active.w, front.active.h, 455 front.active.crop.left, 456 front.active.crop.top, 457 front.active.crop.right, 458 front.active.crop.bottom, 459 front.active.crop.getWidth(), 460 front.active.crop.getHeight(), 461 front.requested.w, front.requested.h, 462 front.requested.crop.left, 463 front.requested.crop.top, 464 front.requested.crop.right, 465 front.requested.crop.bottom, 466 front.requested.crop.getWidth(), 467 front.requested.crop.getHeight()); 468 469 // record the new size, form this point on, when the client request 470 // a buffer, it'll get the new size. 471 mSurfaceTexture->setDefaultBufferSize( 472 temp.requested.w, temp.requested.h); 473 } 474 475 if (!isFixedSize()) { 476 477 const bool resizePending = (temp.requested.w != temp.active.w) || 478 (temp.requested.h != temp.active.h); 479 480 if (resizePending) { 481 // don't let LayerBase::doTransaction update the drawing state 482 // if we have a pending resize, unless we are in fixed-size mode. 483 // the drawing state will be updated only once we receive a buffer 484 // with the correct size. 485 // 486 // in particular, we want to make sure the clip (which is part 487 // of the geometry state) is latched together with the size but is 488 // latched immediately when no resizing is involved. 489 490 flags |= eDontUpdateGeometryState; 491 } 492 } 493 494 return LayerBase::doTransaction(flags); 495} 496 497bool Layer::isFixedSize() const { 498 return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 499} 500 501bool Layer::isCropped() const { 502 return !mCurrentCrop.isEmpty(); 503} 504 505// ---------------------------------------------------------------------------- 506// pageflip handling... 507// ---------------------------------------------------------------------------- 508 509bool Layer::onPreComposition() { 510 mRefreshPending = false; 511 return mQueuedFrames > 0; 512} 513 514void Layer::onPostComposition() { 515 if (mFrameLatencyNeeded) { 516 const HWComposer& hwc = mFlinger->getHwComposer(); 517 const size_t offset = mFrameLatencyOffset; 518 mFrameStats[offset].timestamp = mSurfaceTexture->getTimestamp(); 519 mFrameStats[offset].set = systemTime(); 520 mFrameStats[offset].vsync = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY); 521 mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128; 522 mFrameLatencyNeeded = false; 523 } 524} 525 526Region Layer::latchBuffer(bool& recomputeVisibleRegions) 527{ 528 ATRACE_CALL(); 529 530 Region outDirtyRegion; 531 if (mQueuedFrames > 0) { 532 533 // if we've already called updateTexImage() without going through 534 // a composition step, we have to skip this layer at this point 535 // because we cannot call updateTeximage() without a corresponding 536 // compositionComplete() call. 537 // we'll trigger an update in onPreComposition(). 538 if (mRefreshPending) { 539 return outDirtyRegion; 540 } 541 542 // Capture the old state of the layer for comparisons later 543 const bool oldOpacity = isOpaque(); 544 sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer; 545 546 // signal another event if we have more frames pending 547 if (android_atomic_dec(&mQueuedFrames) > 1) { 548 mFlinger->signalLayerUpdate(); 549 } 550 551 struct Reject : public SurfaceTexture::BufferRejecter { 552 Layer::State& front; 553 Layer::State& current; 554 bool& recomputeVisibleRegions; 555 Reject(Layer::State& front, Layer::State& current, 556 bool& recomputeVisibleRegions) 557 : front(front), current(current), 558 recomputeVisibleRegions(recomputeVisibleRegions) { 559 } 560 561 virtual bool reject(const sp<GraphicBuffer>& buf, 562 const BufferQueue::BufferItem& item) { 563 if (buf == NULL) { 564 return false; 565 } 566 567 uint32_t bufWidth = buf->getWidth(); 568 uint32_t bufHeight = buf->getHeight(); 569 570 // check that we received a buffer of the right size 571 // (Take the buffer's orientation into account) 572 if (item.mTransform & Transform::ROT_90) { 573 swap(bufWidth, bufHeight); 574 } 575 576 577 bool isFixedSize = item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE; 578 if (front.active != front.requested) { 579 580 if (isFixedSize || 581 (bufWidth == front.requested.w && 582 bufHeight == front.requested.h)) 583 { 584 // Here we pretend the transaction happened by updating the 585 // current and drawing states. Drawing state is only accessed 586 // in this thread, no need to have it locked 587 front.active = front.requested; 588 589 // We also need to update the current state so that 590 // we don't end-up overwriting the drawing state with 591 // this stale current state during the next transaction 592 // 593 // NOTE: We don't need to hold the transaction lock here 594 // because State::active is only accessed from this thread. 595 current.active = front.active; 596 597 // recompute visible region 598 recomputeVisibleRegions = true; 599 } 600 601 ALOGD_IF(DEBUG_RESIZE, 602 "latchBuffer/reject: buffer (%ux%u, tr=%02x), scalingMode=%d\n" 603 " drawing={ active ={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }\n" 604 " requested={ wh={%4u,%4u} crop={%4d,%4d,%4d,%4d} (%4d,%4d) }}\n", 605 bufWidth, bufHeight, item.mTransform, item.mScalingMode, 606 front.active.w, front.active.h, 607 front.active.crop.left, 608 front.active.crop.top, 609 front.active.crop.right, 610 front.active.crop.bottom, 611 front.active.crop.getWidth(), 612 front.active.crop.getHeight(), 613 front.requested.w, front.requested.h, 614 front.requested.crop.left, 615 front.requested.crop.top, 616 front.requested.crop.right, 617 front.requested.crop.bottom, 618 front.requested.crop.getWidth(), 619 front.requested.crop.getHeight()); 620 } 621 622 if (!isFixedSize) { 623 if (front.active.w != bufWidth || 624 front.active.h != bufHeight) { 625 // reject this buffer 626 return true; 627 } 628 } 629 return false; 630 } 631 }; 632 633 634 Reject r(mDrawingState, currentState(), recomputeVisibleRegions); 635 636 if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) { 637 // something happened! 638 recomputeVisibleRegions = true; 639 return outDirtyRegion; 640 } 641 642 // update the active buffer 643 mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); 644 if (mActiveBuffer == NULL) { 645 // this can only happen if the very first buffer was rejected. 646 return outDirtyRegion; 647 } 648 649 mRefreshPending = true; 650 mFrameLatencyNeeded = true; 651 if (oldActiveBuffer == NULL) { 652 // the first time we receive a buffer, we need to trigger a 653 // geometry invalidation. 654 mFlinger->invalidateHwcGeometry(); 655 } 656 657 Rect crop(mSurfaceTexture->getCurrentCrop()); 658 const uint32_t transform(mSurfaceTexture->getCurrentTransform()); 659 const uint32_t scalingMode(mSurfaceTexture->getCurrentScalingMode()); 660 if ((crop != mCurrentCrop) || 661 (transform != mCurrentTransform) || 662 (scalingMode != mCurrentScalingMode)) 663 { 664 mCurrentCrop = crop; 665 mCurrentTransform = transform; 666 mCurrentScalingMode = scalingMode; 667 mFlinger->invalidateHwcGeometry(); 668 } 669 670 if (oldActiveBuffer != NULL) { 671 uint32_t bufWidth = mActiveBuffer->getWidth(); 672 uint32_t bufHeight = mActiveBuffer->getHeight(); 673 if (bufWidth != uint32_t(oldActiveBuffer->width) || 674 bufHeight != uint32_t(oldActiveBuffer->height)) { 675 mFlinger->invalidateHwcGeometry(); 676 } 677 } 678 679 mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format); 680 if (oldOpacity != isOpaque()) { 681 recomputeVisibleRegions = true; 682 } 683 684 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 685 glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 686 687 // FIXME: postedRegion should be dirty & bounds 688 const Layer::State& front(drawingState()); 689 Region dirtyRegion(Rect(front.active.w, front.active.h)); 690 691 // transform the dirty region to window-manager space 692 outDirtyRegion = (front.transform.transform(dirtyRegion)); 693 } 694 return outDirtyRegion; 695} 696 697void Layer::dump(String8& result, char* buffer, size_t SIZE) const 698{ 699 LayerBaseClient::dump(result, buffer, SIZE); 700 701 sp<const GraphicBuffer> buf0(mActiveBuffer); 702 uint32_t w0=0, h0=0, s0=0, f0=0; 703 if (buf0 != 0) { 704 w0 = buf0->getWidth(); 705 h0 = buf0->getHeight(); 706 s0 = buf0->getStride(); 707 f0 = buf0->format; 708 } 709 snprintf(buffer, SIZE, 710 " " 711 "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X]," 712 " queued-frames=%d, mRefreshPending=%d\n", 713 mFormat, w0, h0, s0,f0, 714 mQueuedFrames, mRefreshPending); 715 716 result.append(buffer); 717 718 if (mSurfaceTexture != 0) { 719 mSurfaceTexture->dump(result, " ", buffer, SIZE); 720 } 721} 722 723void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const 724{ 725 LayerBaseClient::dumpStats(result, buffer, SIZE); 726 const size_t o = mFrameLatencyOffset; 727 const nsecs_t period = 728 mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); 729 result.appendFormat("%lld\n", period); 730 for (size_t i=0 ; i<128 ; i++) { 731 const size_t index = (o+i) % 128; 732 const nsecs_t time_app = mFrameStats[index].timestamp; 733 const nsecs_t time_set = mFrameStats[index].set; 734 const nsecs_t time_vsync = mFrameStats[index].vsync; 735 result.appendFormat("%lld\t%lld\t%lld\n", 736 time_app, 737 time_vsync, 738 time_set); 739 } 740 result.append("\n"); 741} 742 743void Layer::clearStats() 744{ 745 LayerBaseClient::clearStats(); 746 memset(mFrameStats, 0, sizeof(mFrameStats)); 747} 748 749uint32_t Layer::getEffectiveUsage(uint32_t usage) const 750{ 751 // TODO: should we do something special if mSecure is set? 752 if (mProtectedByApp) { 753 // need a hardware-protected path to external video sink 754 usage |= GraphicBuffer::USAGE_PROTECTED; 755 } 756 usage |= GraphicBuffer::USAGE_HW_COMPOSER; 757 return usage; 758} 759 760void Layer::updateTransformHint() const { 761 uint32_t orientation = 0; 762 if (!mFlinger->mDebugDisableTransformHint) { 763 // The transform hint is used to improve performance on the main 764 // display -- we can only have a single transform hint, it cannot 765 // apply to all displays. 766 // This is why we use the default display here. This is not an 767 // oversight. 768 sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice()); 769 const Transform& planeTransform(hw->getTransform()); 770 orientation = planeTransform.getOrientation(); 771 if (orientation & Transform::ROT_INVALID) { 772 orientation = 0; 773 } 774 } 775 mSurfaceTexture->setTransformHint(orientation); 776} 777 778// --------------------------------------------------------------------------- 779 780 781}; // namespace android 782