DisplayDevice.cpp revision b02087dbd6a25e9d077fde16039050da8012b413
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 : lastCompositionHadVisibleLayers(false), 81 mFlinger(flinger), 82 mType(type), 83 mHwcDisplayId(hwcId), 84 mDisplayToken(displayToken), 85 mDisplaySurface(displaySurface), 86 mDisplay(EGL_NO_DISPLAY), 87 mSurface(EGL_NO_SURFACE), 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 /* 105 * Create our display's surface 106 */ 107 108 EGLSurface eglSurface; 109 EGLDisplay display = mFlinger->getRenderEngine().getEGLDisplay(); 110 EGLConfig config = mFlinger->getRenderEngine().getEGLConfig(); 111 112 if (config == EGL_NO_CONFIG) { 113 config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888, 114 /*logConfig*/ false); 115 } 116 eglSurface = eglCreateWindowSurface(display, config, window, NULL); 117 eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth); 118 eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight); 119 120 // Make sure that composition can never be stalled by a virtual display 121 // consumer that isn't processing buffers fast enough. We have to do this 122 // in two places: 123 // * Here, in case the display is composed entirely by HWC. 124 // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the 125 // window's swap interval in eglMakeCurrent, so they'll override the 126 // interval we set here. 127 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 128 window->setSwapInterval(window, 0); 129 130 mConfig = config; 131 mDisplay = display; 132 mSurface = eglSurface; 133 mPageFlipCount = 0; 134 mViewport.makeInvalid(); 135 mFrame.makeInvalid(); 136 137 // virtual displays are always considered enabled 138 mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ? 139 HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF; 140 141 // Name the display. The name will be replaced shortly if the display 142 // was created with createDisplay(). 143 switch (mType) { 144 case DISPLAY_PRIMARY: 145 mDisplayName = "Built-in Screen"; 146 break; 147 case DISPLAY_EXTERNAL: 148 mDisplayName = "HDMI Screen"; 149 break; 150 default: 151 mDisplayName = "Virtual Screen"; // e.g. Overlay #n 152 break; 153 } 154 155 // initialize the display orientation transform. 156 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame); 157 158 if (useTripleFramebuffer) { 159 surface->allocateBuffers(); 160 } 161} 162 163DisplayDevice::~DisplayDevice() { 164 if (mSurface != EGL_NO_SURFACE) { 165 eglDestroySurface(mDisplay, mSurface); 166 mSurface = EGL_NO_SURFACE; 167 } 168} 169 170void DisplayDevice::disconnect(HWComposer& hwc) { 171 if (mHwcDisplayId >= 0) { 172 hwc.disconnectDisplay(mHwcDisplayId); 173 mHwcDisplayId = -1; 174 } 175} 176 177bool DisplayDevice::isValid() const { 178 return mFlinger != NULL; 179} 180 181int DisplayDevice::getWidth() const { 182 return mDisplayWidth; 183} 184 185int DisplayDevice::getHeight() const { 186 return mDisplayHeight; 187} 188 189EGLSurface DisplayDevice::getEGLSurface() const { 190 return mSurface; 191} 192 193void DisplayDevice::setDisplayName(const String8& displayName) { 194 if (!displayName.isEmpty()) { 195 // never override the name with an empty name 196 mDisplayName = displayName; 197 } 198} 199 200uint32_t DisplayDevice::getPageFlipCount() const { 201 return mPageFlipCount; 202} 203 204void DisplayDevice::flip() const 205{ 206 mFlinger->getRenderEngine().checkErrors(); 207 mPageFlipCount++; 208} 209 210status_t DisplayDevice::beginFrame(bool mustRecompose) const { 211 return mDisplaySurface->beginFrame(mustRecompose); 212} 213 214status_t DisplayDevice::prepareFrame(HWComposer& hwc) { 215 status_t error = hwc.prepare(*this); 216 if (error != NO_ERROR) { 217 return error; 218 } 219 220 DisplaySurface::CompositionType compositionType; 221 bool hasClient = hwc.hasClientComposition(mHwcDisplayId); 222 bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId); 223 if (hasClient && hasDevice) { 224 compositionType = DisplaySurface::COMPOSITION_MIXED; 225 } else if (hasClient) { 226 compositionType = DisplaySurface::COMPOSITION_GLES; 227 } else if (hasDevice) { 228 compositionType = DisplaySurface::COMPOSITION_HWC; 229 } else { 230 // Nothing to do -- when turning the screen off we get a frame like 231 // this. Call it a HWC frame since we won't be doing any GLES work but 232 // will do a prepare/set cycle. 233 compositionType = DisplaySurface::COMPOSITION_HWC; 234 } 235 return mDisplaySurface->prepareFrame(compositionType); 236} 237 238void DisplayDevice::swapBuffers(HWComposer& hwc) const { 239 if (hwc.hasClientComposition(mHwcDisplayId)) { 240 EGLBoolean success = eglSwapBuffers(mDisplay, mSurface); 241 if (!success) { 242 EGLint error = eglGetError(); 243 if (error == EGL_CONTEXT_LOST || 244 mType == DisplayDevice::DISPLAY_PRIMARY) { 245 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x", 246 mDisplay, mSurface, error); 247 } else { 248 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x", 249 mDisplay, mSurface, error); 250 } 251 } 252 } 253 254 status_t result = mDisplaySurface->advanceFrame(); 255 if (result != NO_ERROR) { 256 ALOGE("[%s] failed pushing new frame to HWC: %d", 257 mDisplayName.string(), result); 258 } 259} 260 261void DisplayDevice::onSwapBuffersCompleted() const { 262 mDisplaySurface->onFrameCommitted(); 263} 264 265EGLBoolean DisplayDevice::makeCurrent() const { 266 EGLBoolean result = EGL_TRUE; 267 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 268 if (sur != mSurface) { 269 result = mFlinger->getRenderEngine().setCurrentSurface(mSurface); 270 if (result == EGL_TRUE) { 271 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 272 eglSwapInterval(mDisplay, 0); 273 } 274 } 275 setViewportAndProjection(); 276 return result; 277} 278 279void DisplayDevice::setViewportAndProjection() const { 280 size_t w = mDisplayWidth; 281 size_t h = mDisplayHeight; 282 Rect sourceCrop(0, 0, w, h); 283 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, 284 false, Transform::ROT_0); 285} 286 287const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const { 288 return mDisplaySurface->getClientTargetAcquireFence(); 289} 290 291// ---------------------------------------------------------------------------- 292 293void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { 294 mVisibleLayersSortedByZ = layers; 295} 296 297const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { 298 return mVisibleLayersSortedByZ; 299} 300 301void DisplayDevice::setLayersNeedingFences(const Vector< sp<Layer> >& layers) { 302 mLayersNeedingFences = layers; 303} 304 305const Vector< sp<Layer> >& DisplayDevice::getLayersNeedingFences() const { 306 return mLayersNeedingFences; 307} 308 309Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 310 Region dirty; 311 if (repaintEverything) { 312 dirty.set(getBounds()); 313 } else { 314 const Transform& planeTransform(mGlobalTransform); 315 dirty = planeTransform.transform(this->dirtyRegion); 316 dirty.andSelf(getBounds()); 317 } 318 return dirty; 319} 320 321// ---------------------------------------------------------------------------- 322void DisplayDevice::setPowerMode(int mode) { 323 mPowerMode = mode; 324} 325 326int DisplayDevice::getPowerMode() const { 327 return mPowerMode; 328} 329 330bool DisplayDevice::isDisplayOn() const { 331 return (mPowerMode != HWC_POWER_MODE_OFF); 332} 333 334// ---------------------------------------------------------------------------- 335void DisplayDevice::setActiveConfig(int mode) { 336 mActiveConfig = mode; 337} 338 339int DisplayDevice::getActiveConfig() const { 340 return mActiveConfig; 341} 342 343// ---------------------------------------------------------------------------- 344void DisplayDevice::setActiveColorMode(android_color_mode_t mode) { 345 mActiveColorMode = mode; 346} 347 348android_color_mode_t DisplayDevice::getActiveColorMode() const { 349 return mActiveColorMode; 350} 351 352void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) { 353 ANativeWindow* const window = mNativeWindow.get(); 354 native_window_set_buffers_data_space(window, dataspace); 355} 356 357// ---------------------------------------------------------------------------- 358 359void DisplayDevice::setLayerStack(uint32_t stack) { 360 mLayerStack = stack; 361 dirtyRegion.set(bounds()); 362} 363 364// ---------------------------------------------------------------------------- 365 366uint32_t DisplayDevice::getOrientationTransform() const { 367 uint32_t transform = 0; 368 switch (mOrientation) { 369 case DisplayState::eOrientationDefault: 370 transform = Transform::ROT_0; 371 break; 372 case DisplayState::eOrientation90: 373 transform = Transform::ROT_90; 374 break; 375 case DisplayState::eOrientation180: 376 transform = Transform::ROT_180; 377 break; 378 case DisplayState::eOrientation270: 379 transform = Transform::ROT_270; 380 break; 381 } 382 return transform; 383} 384 385status_t DisplayDevice::orientationToTransfrom( 386 int orientation, int w, int h, Transform* tr) 387{ 388 uint32_t flags = 0; 389 switch (orientation) { 390 case DisplayState::eOrientationDefault: 391 flags = Transform::ROT_0; 392 break; 393 case DisplayState::eOrientation90: 394 flags = Transform::ROT_90; 395 break; 396 case DisplayState::eOrientation180: 397 flags = Transform::ROT_180; 398 break; 399 case DisplayState::eOrientation270: 400 flags = Transform::ROT_270; 401 break; 402 default: 403 return BAD_VALUE; 404 } 405 tr->set(flags, w, h); 406 return NO_ERROR; 407} 408 409void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) { 410 dirtyRegion.set(getBounds()); 411 412 if (mSurface != EGL_NO_SURFACE) { 413 eglDestroySurface(mDisplay, mSurface); 414 mSurface = EGL_NO_SURFACE; 415 } 416 417 mDisplaySurface->resizeBuffers(newWidth, newHeight); 418 419 ANativeWindow* const window = mNativeWindow.get(); 420 mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL); 421 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth); 422 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight); 423 424 LOG_FATAL_IF(mDisplayWidth != newWidth, 425 "Unable to set new width to %d", newWidth); 426 LOG_FATAL_IF(mDisplayHeight != newHeight, 427 "Unable to set new height to %d", newHeight); 428} 429 430void DisplayDevice::setProjection(int orientation, 431 const Rect& newViewport, const Rect& newFrame) { 432 Rect viewport(newViewport); 433 Rect frame(newFrame); 434 435 const int w = mDisplayWidth; 436 const int h = mDisplayHeight; 437 438 Transform R; 439 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 440 441 if (!frame.isValid()) { 442 // the destination frame can be invalid if it has never been set, 443 // in that case we assume the whole display frame. 444 frame = Rect(w, h); 445 } 446 447 if (viewport.isEmpty()) { 448 // viewport can be invalid if it has never been set, in that case 449 // we assume the whole display size. 450 // it's also invalid to have an empty viewport, so we handle that 451 // case in the same way. 452 viewport = Rect(w, h); 453 if (R.getOrientation() & Transform::ROT_90) { 454 // viewport is always specified in the logical orientation 455 // of the display (ie: post-rotation). 456 swap(viewport.right, viewport.bottom); 457 } 458 } 459 460 dirtyRegion.set(getBounds()); 461 462 Transform TL, TP, S; 463 float src_width = viewport.width(); 464 float src_height = viewport.height(); 465 float dst_width = frame.width(); 466 float dst_height = frame.height(); 467 if (src_width != dst_width || src_height != dst_height) { 468 float sx = dst_width / src_width; 469 float sy = dst_height / src_height; 470 S.set(sx, 0, 0, sy); 471 } 472 473 float src_x = viewport.left; 474 float src_y = viewport.top; 475 float dst_x = frame.left; 476 float dst_y = frame.top; 477 TL.set(-src_x, -src_y); 478 TP.set(dst_x, dst_y); 479 480 // The viewport and frame are both in the logical orientation. 481 // Apply the logical translation, scale to physical size, apply the 482 // physical translation and finally rotate to the physical orientation. 483 mGlobalTransform = R * TP * S * TL; 484 485 const uint8_t type = mGlobalTransform.getType(); 486 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 487 (type >= Transform::SCALE)); 488 489 mScissor = mGlobalTransform.transform(viewport); 490 if (mScissor.isEmpty()) { 491 mScissor = getBounds(); 492 } 493 494 mOrientation = orientation; 495 if (mType == DisplayType::DISPLAY_PRIMARY) { 496 uint32_t transform = 0; 497 switch (mOrientation) { 498 case DisplayState::eOrientationDefault: 499 transform = Transform::ROT_0; 500 break; 501 case DisplayState::eOrientation90: 502 transform = Transform::ROT_90; 503 break; 504 case DisplayState::eOrientation180: 505 transform = Transform::ROT_180; 506 break; 507 case DisplayState::eOrientation270: 508 transform = Transform::ROT_270; 509 break; 510 } 511 sPrimaryDisplayOrientation = transform; 512 } 513 mViewport = viewport; 514 mFrame = frame; 515} 516 517uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() { 518 return sPrimaryDisplayOrientation; 519} 520 521void DisplayDevice::dump(String8& result) const { 522 const Transform& tr(mGlobalTransform); 523 ANativeWindow* const window = mNativeWindow.get(); 524 EGLint redSize, greenSize, blueSize, alphaSize; 525 eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &redSize); 526 eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &greenSize); 527 eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &blueSize); 528 eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &alphaSize); 529 result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string()); 530 result.appendFormat(" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p " 531 "(%d:%d:%d:%d), orient=%2d (type=%08x), " 532 "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n", 533 mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, window, 534 redSize, greenSize, blueSize, alphaSize, mOrientation, tr.getType(), 535 getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig, 536 mVisibleLayersSortedByZ.size()); 537 result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 538 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 539 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 540 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, mScissor.left, 541 mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0], 542 tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]); 543 auto const surface = static_cast<Surface*>(window); 544 android_dataspace dataspace = surface->getBuffersDataSpace(); 545 result.appendFormat(" dataspace: %s (%d)\n", dataspaceDetails(dataspace).c_str(), dataspace); 546 547 String8 surfaceDump; 548 mDisplaySurface->dumpAsString(surfaceDump); 549 result.append(surfaceDump); 550} 551 552std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1); 553 554DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure) 555 : type(type), 556 layerStack(DisplayDevice::NO_LAYER_STACK), 557 orientation(0), 558 width(0), 559 height(0), 560 isSecure(isSecure) 561{ 562 viewport.makeInvalid(); 563 frame.makeInvalid(); 564} 565