DisplayDevice.cpp revision 144e116f45f196396f0d59d5fc09766ab618f885
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 LOG_NDEBUG 0 18#undef LOG_TAG 19#define LOG_TAG "DisplayDevice" 20 21#include <stdlib.h> 22#include <stdio.h> 23#include <string.h> 24#include <math.h> 25 26#include <cutils/properties.h> 27 28#include <utils/RefBase.h> 29#include <utils/Log.h> 30 31#include <ui/DebugUtils.h> 32#include <ui/DisplayInfo.h> 33#include <ui/PixelFormat.h> 34 35#include <gui/Surface.h> 36 37#include <hardware/gralloc.h> 38 39#include "DisplayHardware/DisplaySurface.h" 40#include "DisplayHardware/HWComposer.h" 41#include "DisplayHardware/HWC2.h" 42#include "RenderEngine/RenderEngine.h" 43 44#include "clz.h" 45#include "DisplayDevice.h" 46#include "SurfaceFlinger.h" 47#include "Layer.h" 48 49#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> 50#include <configstore/Utils.h> 51 52// ---------------------------------------------------------------------------- 53using namespace android; 54// ---------------------------------------------------------------------------- 55 56// retrieve triple buffer setting from configstore 57using namespace android::hardware::configstore; 58using namespace android::hardware::configstore::V1_0; 59 60static bool useTripleFramebuffer = getInt64< ISurfaceFlingerConfigs, 61 &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2) >= 3; 62 63/* 64 * Initialize the display to the specified values. 65 * 66 */ 67 68uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0; 69 70// clang-format off 71DisplayDevice::DisplayDevice( 72 const sp<SurfaceFlinger>& flinger, 73 DisplayType type, 74 int32_t hwcId, 75 bool isSecure, 76 const wp<IBinder>& displayToken, 77 const sp<DisplaySurface>& displaySurface, 78 const sp<IGraphicBufferProducer>& producer, 79 bool supportWideColor, 80 bool supportHdr) 81 : lastCompositionHadVisibleLayers(false), 82 mFlinger(flinger), 83 mType(type), 84 mHwcDisplayId(hwcId), 85 mDisplayToken(displayToken), 86 mDisplaySurface(displaySurface), 87 mSurface{flinger->getRenderEngine().createSurface()}, 88 mDisplayWidth(), 89 mDisplayHeight(), 90 mPageFlipCount(), 91 mIsSecure(isSecure), 92 mLayerStack(NO_LAYER_STACK), 93 mOrientation(), 94 mPowerMode(HWC_POWER_MODE_OFF), 95 mActiveConfig(0) 96{ 97 // clang-format on 98 Surface* surface; 99 mNativeWindow = surface = new Surface(producer, false); 100 ANativeWindow* const window = mNativeWindow.get(); 101 102 mActiveColorMode = HAL_COLOR_MODE_NATIVE; 103 mDisplayHasWideColor = supportWideColor; 104 mDisplayHasHdr = supportHdr; 105 106 /* 107 * Create our display's surface 108 */ 109 mSurface->setCritical(mType == DisplayDevice::DISPLAY_PRIMARY); 110 mSurface->setAsync(mType >= DisplayDevice::DISPLAY_VIRTUAL); 111 mSurface->setNativeWindow(window); 112 mDisplayWidth = mSurface->queryWidth(); 113 mDisplayHeight = mSurface->queryHeight(); 114 115 // Make sure that composition can never be stalled by a virtual display 116 // consumer that isn't processing buffers fast enough. We have to do this 117 // in two places: 118 // * Here, in case the display is composed entirely by HWC. 119 // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the 120 // window's swap interval in eglMakeCurrent, so they'll override the 121 // interval we set here. 122 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 123 window->setSwapInterval(window, 0); 124 125 mPageFlipCount = 0; 126 mViewport.makeInvalid(); 127 mFrame.makeInvalid(); 128 129 // virtual displays are always considered enabled 130 mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ? 131 HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF; 132 133 // initialize the display orientation transform. 134 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame); 135 136 if (useTripleFramebuffer) { 137 surface->allocateBuffers(); 138 } 139} 140 141DisplayDevice::~DisplayDevice() { 142} 143 144void DisplayDevice::disconnect(HWComposer& hwc) { 145 if (mHwcDisplayId >= 0) { 146 hwc.disconnectDisplay(mHwcDisplayId); 147 mHwcDisplayId = -1; 148 } 149} 150 151bool DisplayDevice::isValid() const { 152 return mFlinger != nullptr; 153} 154 155int DisplayDevice::getWidth() const { 156 return mDisplayWidth; 157} 158 159int DisplayDevice::getHeight() const { 160 return mDisplayHeight; 161} 162 163void DisplayDevice::setDisplayName(const String8& displayName) { 164 if (!displayName.isEmpty()) { 165 // never override the name with an empty name 166 mDisplayName = displayName; 167 } 168} 169 170uint32_t DisplayDevice::getPageFlipCount() const { 171 return mPageFlipCount; 172} 173 174void DisplayDevice::flip() const 175{ 176 mFlinger->getRenderEngine().checkErrors(); 177 mPageFlipCount++; 178} 179 180status_t DisplayDevice::beginFrame(bool mustRecompose) const { 181 return mDisplaySurface->beginFrame(mustRecompose); 182} 183 184status_t DisplayDevice::prepareFrame(HWComposer& hwc) { 185 status_t error = hwc.prepare(*this); 186 if (error != NO_ERROR) { 187 return error; 188 } 189 190 DisplaySurface::CompositionType compositionType; 191 bool hasClient = hwc.hasClientComposition(mHwcDisplayId); 192 bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId); 193 if (hasClient && hasDevice) { 194 compositionType = DisplaySurface::COMPOSITION_MIXED; 195 } else if (hasClient) { 196 compositionType = DisplaySurface::COMPOSITION_GLES; 197 } else if (hasDevice) { 198 compositionType = DisplaySurface::COMPOSITION_HWC; 199 } else { 200 // Nothing to do -- when turning the screen off we get a frame like 201 // this. Call it a HWC frame since we won't be doing any GLES work but 202 // will do a prepare/set cycle. 203 compositionType = DisplaySurface::COMPOSITION_HWC; 204 } 205 return mDisplaySurface->prepareFrame(compositionType); 206} 207 208void DisplayDevice::swapBuffers(HWComposer& hwc) const { 209 if (hwc.hasClientComposition(mHwcDisplayId) || hwc.hasFlipClientTargetRequest(mHwcDisplayId)) { 210 mSurface->swapBuffers(); 211 } 212 213 status_t result = mDisplaySurface->advanceFrame(); 214 if (result != NO_ERROR) { 215 ALOGE("[%s] failed pushing new frame to HWC: %d", 216 mDisplayName.string(), result); 217 } 218} 219 220void DisplayDevice::onSwapBuffersCompleted() const { 221 mDisplaySurface->onFrameCommitted(); 222} 223 224bool DisplayDevice::makeCurrent() const { 225 bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface); 226 setViewportAndProjection(); 227 return success; 228} 229 230void DisplayDevice::setViewportAndProjection() const { 231 size_t w = mDisplayWidth; 232 size_t h = mDisplayHeight; 233 Rect sourceCrop(0, 0, w, h); 234 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, 235 false, Transform::ROT_0); 236} 237 238const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const { 239 return mDisplaySurface->getClientTargetAcquireFence(); 240} 241 242// ---------------------------------------------------------------------------- 243 244void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { 245 mVisibleLayersSortedByZ = layers; 246} 247 248const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { 249 return mVisibleLayersSortedByZ; 250} 251 252void DisplayDevice::setLayersNeedingFences(const Vector< sp<Layer> >& layers) { 253 mLayersNeedingFences = layers; 254} 255 256const Vector< sp<Layer> >& DisplayDevice::getLayersNeedingFences() const { 257 return mLayersNeedingFences; 258} 259 260Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 261 Region dirty; 262 if (repaintEverything) { 263 dirty.set(getBounds()); 264 } else { 265 const Transform& planeTransform(mGlobalTransform); 266 dirty = planeTransform.transform(this->dirtyRegion); 267 dirty.andSelf(getBounds()); 268 } 269 return dirty; 270} 271 272// ---------------------------------------------------------------------------- 273void DisplayDevice::setPowerMode(int mode) { 274 mPowerMode = mode; 275} 276 277int DisplayDevice::getPowerMode() const { 278 return mPowerMode; 279} 280 281bool DisplayDevice::isDisplayOn() const { 282 return (mPowerMode != HWC_POWER_MODE_OFF); 283} 284 285// ---------------------------------------------------------------------------- 286void DisplayDevice::setActiveConfig(int mode) { 287 mActiveConfig = mode; 288} 289 290int DisplayDevice::getActiveConfig() const { 291 return mActiveConfig; 292} 293 294// ---------------------------------------------------------------------------- 295void DisplayDevice::setActiveColorMode(android_color_mode_t mode) { 296 mActiveColorMode = mode; 297} 298 299android_color_mode_t DisplayDevice::getActiveColorMode() const { 300 return mActiveColorMode; 301} 302 303void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) { 304 ANativeWindow* const window = mNativeWindow.get(); 305 native_window_set_buffers_data_space(window, dataspace); 306} 307 308// ---------------------------------------------------------------------------- 309 310void DisplayDevice::setLayerStack(uint32_t stack) { 311 mLayerStack = stack; 312 dirtyRegion.set(bounds()); 313} 314 315// ---------------------------------------------------------------------------- 316 317uint32_t DisplayDevice::getOrientationTransform() const { 318 uint32_t transform = 0; 319 switch (mOrientation) { 320 case DisplayState::eOrientationDefault: 321 transform = Transform::ROT_0; 322 break; 323 case DisplayState::eOrientation90: 324 transform = Transform::ROT_90; 325 break; 326 case DisplayState::eOrientation180: 327 transform = Transform::ROT_180; 328 break; 329 case DisplayState::eOrientation270: 330 transform = Transform::ROT_270; 331 break; 332 } 333 return transform; 334} 335 336status_t DisplayDevice::orientationToTransfrom( 337 int orientation, int w, int h, Transform* tr) 338{ 339 uint32_t flags = 0; 340 switch (orientation) { 341 case DisplayState::eOrientationDefault: 342 flags = Transform::ROT_0; 343 break; 344 case DisplayState::eOrientation90: 345 flags = Transform::ROT_90; 346 break; 347 case DisplayState::eOrientation180: 348 flags = Transform::ROT_180; 349 break; 350 case DisplayState::eOrientation270: 351 flags = Transform::ROT_270; 352 break; 353 default: 354 return BAD_VALUE; 355 } 356 tr->set(flags, w, h); 357 return NO_ERROR; 358} 359 360void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) { 361 dirtyRegion.set(getBounds()); 362 363 mSurface->setNativeWindow(nullptr); 364 365 mDisplaySurface->resizeBuffers(newWidth, newHeight); 366 367 ANativeWindow* const window = mNativeWindow.get(); 368 mSurface->setNativeWindow(window); 369 mDisplayWidth = mSurface->queryWidth(); 370 mDisplayHeight = mSurface->queryHeight(); 371 372 LOG_FATAL_IF(mDisplayWidth != newWidth, 373 "Unable to set new width to %d", newWidth); 374 LOG_FATAL_IF(mDisplayHeight != newHeight, 375 "Unable to set new height to %d", newHeight); 376} 377 378void DisplayDevice::setProjection(int orientation, 379 const Rect& newViewport, const Rect& newFrame) { 380 Rect viewport(newViewport); 381 Rect frame(newFrame); 382 383 const int w = mDisplayWidth; 384 const int h = mDisplayHeight; 385 386 Transform R; 387 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 388 389 if (!frame.isValid()) { 390 // the destination frame can be invalid if it has never been set, 391 // in that case we assume the whole display frame. 392 frame = Rect(w, h); 393 } 394 395 if (viewport.isEmpty()) { 396 // viewport can be invalid if it has never been set, in that case 397 // we assume the whole display size. 398 // it's also invalid to have an empty viewport, so we handle that 399 // case in the same way. 400 viewport = Rect(w, h); 401 if (R.getOrientation() & Transform::ROT_90) { 402 // viewport is always specified in the logical orientation 403 // of the display (ie: post-rotation). 404 swap(viewport.right, viewport.bottom); 405 } 406 } 407 408 dirtyRegion.set(getBounds()); 409 410 Transform TL, TP, S; 411 float src_width = viewport.width(); 412 float src_height = viewport.height(); 413 float dst_width = frame.width(); 414 float dst_height = frame.height(); 415 if (src_width != dst_width || src_height != dst_height) { 416 float sx = dst_width / src_width; 417 float sy = dst_height / src_height; 418 S.set(sx, 0, 0, sy); 419 } 420 421 float src_x = viewport.left; 422 float src_y = viewport.top; 423 float dst_x = frame.left; 424 float dst_y = frame.top; 425 TL.set(-src_x, -src_y); 426 TP.set(dst_x, dst_y); 427 428 // The viewport and frame are both in the logical orientation. 429 // Apply the logical translation, scale to physical size, apply the 430 // physical translation and finally rotate to the physical orientation. 431 mGlobalTransform = R * TP * S * TL; 432 433 const uint8_t type = mGlobalTransform.getType(); 434 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 435 (type >= Transform::SCALE)); 436 437 mScissor = mGlobalTransform.transform(viewport); 438 if (mScissor.isEmpty()) { 439 mScissor = getBounds(); 440 } 441 442 mOrientation = orientation; 443 if (mType == DisplayType::DISPLAY_PRIMARY) { 444 uint32_t transform = 0; 445 switch (mOrientation) { 446 case DisplayState::eOrientationDefault: 447 transform = Transform::ROT_0; 448 break; 449 case DisplayState::eOrientation90: 450 transform = Transform::ROT_90; 451 break; 452 case DisplayState::eOrientation180: 453 transform = Transform::ROT_180; 454 break; 455 case DisplayState::eOrientation270: 456 transform = Transform::ROT_270; 457 break; 458 } 459 sPrimaryDisplayOrientation = transform; 460 } 461 mViewport = viewport; 462 mFrame = frame; 463} 464 465uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() { 466 return sPrimaryDisplayOrientation; 467} 468 469void DisplayDevice::dump(String8& result) const { 470 const Transform& tr(mGlobalTransform); 471 ANativeWindow* const window = mNativeWindow.get(); 472 result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string()); 473 result.appendFormat(" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p " 474 "(%d:%d:%d:%d), orient=%2d (type=%08x), " 475 "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n", 476 mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, window, 477 mSurface->queryRedSize(), mSurface->queryGreenSize(), 478 mSurface->queryBlueSize(), mSurface->queryAlphaSize(), mOrientation, 479 tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig, 480 mVisibleLayersSortedByZ.size()); 481 result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 482 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 483 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 484 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, mScissor.left, 485 mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0], 486 tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]); 487 auto const surface = static_cast<Surface*>(window); 488 android_dataspace dataspace = surface->getBuffersDataSpace(); 489 result.appendFormat(" dataspace: %s (%d)\n", dataspaceDetails(dataspace).c_str(), dataspace); 490 491 String8 surfaceDump; 492 mDisplaySurface->dumpAsString(surfaceDump); 493 result.append(surfaceDump); 494} 495 496std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1); 497 498DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure) 499 : type(type), 500 layerStack(DisplayDevice::NO_LAYER_STACK), 501 orientation(0), 502 width(0), 503 height(0), 504 isSecure(isSecure) 505{ 506 viewport.makeInvalid(); 507 frame.makeInvalid(); 508} 509