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/DisplayInfo.h> 32 #include <ui/PixelFormat.h> 33 34 #include <gui/Surface.h> 35 36 #include <hardware/gralloc.h> 37 38 #include "DisplayHardware/DisplaySurface.h" 39 #include "DisplayHardware/HWComposer.h" 40 #ifdef USE_HWC2 41 #include "DisplayHardware/HWC2.h" 42 #endif 43 #include "RenderEngine/RenderEngine.h" 44 45 #include "clz.h" 46 #include "DisplayDevice.h" 47 #include "SurfaceFlinger.h" 48 #include "Layer.h" 49 50 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> 51 #include <configstore/Utils.h> 52 53 // ---------------------------------------------------------------------------- 54 using namespace android; 55 // ---------------------------------------------------------------------------- 56 57 #ifdef EGL_ANDROID_swap_rectangle 58 static constexpr bool kEGLAndroidSwapRectangle = true; 59 #else 60 static constexpr bool kEGLAndroidSwapRectangle = false; 61 #endif 62 63 // retrieve triple buffer setting from configstore 64 using namespace android::hardware::configstore; 65 using namespace android::hardware::configstore::V1_0; 66 67 static bool useTripleFramebuffer = getInt64< ISurfaceFlingerConfigs, 68 &ISurfaceFlingerConfigs::maxFrameBufferAcquiredBuffers>(2) == 3; 69 70 #if !defined(EGL_EGLEXT_PROTOTYPES) || !defined(EGL_ANDROID_swap_rectangle) 71 // Dummy implementation in case it is missing. 72 inline void eglSetSwapRectangleANDROID (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) { 73 } 74 #endif 75 76 /* 77 * Initialize the display to the specified values. 78 * 79 */ 80 81 uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0; 82 83 // clang-format off 84 DisplayDevice::DisplayDevice( 85 const sp<SurfaceFlinger>& flinger, 86 DisplayType type, 87 int32_t hwcId, 88 #ifndef USE_HWC2 89 int format, 90 #endif 91 bool isSecure, 92 const wp<IBinder>& displayToken, 93 const sp<DisplaySurface>& displaySurface, 94 const sp<IGraphicBufferProducer>& producer, 95 EGLConfig config, 96 bool supportWideColor) 97 : lastCompositionHadVisibleLayers(false), 98 mFlinger(flinger), 99 mType(type), 100 mHwcDisplayId(hwcId), 101 mDisplayToken(displayToken), 102 mDisplaySurface(displaySurface), 103 mDisplay(EGL_NO_DISPLAY), 104 mSurface(EGL_NO_SURFACE), 105 mDisplayWidth(), 106 mDisplayHeight(), 107 #ifndef USE_HWC2 108 mFormat(), 109 #endif 110 mFlags(), 111 mPageFlipCount(), 112 mIsSecure(isSecure), 113 mLayerStack(NO_LAYER_STACK), 114 mOrientation(), 115 mPowerMode(HWC_POWER_MODE_OFF), 116 mActiveConfig(0) 117 { 118 // clang-format on 119 Surface* surface; 120 mNativeWindow = surface = new Surface(producer, false); 121 ANativeWindow* const window = mNativeWindow.get(); 122 123 #ifdef USE_HWC2 124 mActiveColorMode = HAL_COLOR_MODE_NATIVE; 125 mDisplayHasWideColor = supportWideColor; 126 #else 127 (void) supportWideColor; 128 #endif 129 /* 130 * Create our display's surface 131 */ 132 133 EGLSurface eglSurface; 134 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 135 if (config == EGL_NO_CONFIG) { 136 #ifdef USE_HWC2 137 config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888, 138 /*logConfig*/ false); 139 #else 140 config = RenderEngine::chooseEglConfig(display, format, 141 /*logConfig*/ false); 142 #endif 143 } 144 eglSurface = eglCreateWindowSurface(display, config, window, NULL); 145 eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth); 146 eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight); 147 148 // Make sure that composition can never be stalled by a virtual display 149 // consumer that isn't processing buffers fast enough. We have to do this 150 // in two places: 151 // * Here, in case the display is composed entirely by HWC. 152 // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the 153 // window's swap interval in eglMakeCurrent, so they'll override the 154 // interval we set here. 155 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 156 window->setSwapInterval(window, 0); 157 158 mConfig = config; 159 mDisplay = display; 160 mSurface = eglSurface; 161 #ifndef USE_HWC2 162 mFormat = format; 163 #endif 164 mPageFlipCount = 0; 165 mViewport.makeInvalid(); 166 mFrame.makeInvalid(); 167 168 // virtual displays are always considered enabled 169 mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ? 170 HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF; 171 172 // Name the display. The name will be replaced shortly if the display 173 // was created with createDisplay(). 174 switch (mType) { 175 case DISPLAY_PRIMARY: 176 mDisplayName = "Built-in Screen"; 177 break; 178 case DISPLAY_EXTERNAL: 179 mDisplayName = "HDMI Screen"; 180 break; 181 default: 182 mDisplayName = "Virtual Screen"; // e.g. Overlay #n 183 break; 184 } 185 186 // initialize the display orientation transform. 187 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame); 188 189 if (useTripleFramebuffer) { 190 surface->allocateBuffers(); 191 } 192 } 193 194 DisplayDevice::~DisplayDevice() { 195 if (mSurface != EGL_NO_SURFACE) { 196 eglDestroySurface(mDisplay, mSurface); 197 mSurface = EGL_NO_SURFACE; 198 } 199 } 200 201 void DisplayDevice::disconnect(HWComposer& hwc) { 202 if (mHwcDisplayId >= 0) { 203 hwc.disconnectDisplay(mHwcDisplayId); 204 #ifndef USE_HWC2 205 if (mHwcDisplayId >= DISPLAY_VIRTUAL) 206 hwc.freeDisplayId(mHwcDisplayId); 207 #endif 208 mHwcDisplayId = -1; 209 } 210 } 211 212 bool DisplayDevice::isValid() const { 213 return mFlinger != NULL; 214 } 215 216 int DisplayDevice::getWidth() const { 217 return mDisplayWidth; 218 } 219 220 int DisplayDevice::getHeight() const { 221 return mDisplayHeight; 222 } 223 224 #ifndef USE_HWC2 225 PixelFormat DisplayDevice::getFormat() const { 226 return mFormat; 227 } 228 #endif 229 230 EGLSurface DisplayDevice::getEGLSurface() const { 231 return mSurface; 232 } 233 234 void DisplayDevice::setDisplayName(const String8& displayName) { 235 if (!displayName.isEmpty()) { 236 // never override the name with an empty name 237 mDisplayName = displayName; 238 } 239 } 240 241 uint32_t DisplayDevice::getPageFlipCount() const { 242 return mPageFlipCount; 243 } 244 245 #ifndef USE_HWC2 246 status_t DisplayDevice::compositionComplete() const { 247 return mDisplaySurface->compositionComplete(); 248 } 249 #endif 250 251 void DisplayDevice::flip(const Region& dirty) const 252 { 253 mFlinger->getRenderEngine().checkErrors(); 254 255 if (kEGLAndroidSwapRectangle) { 256 if (mFlags & SWAP_RECTANGLE) { 257 const Region newDirty(dirty.intersect(bounds())); 258 const Rect b(newDirty.getBounds()); 259 eglSetSwapRectangleANDROID(mDisplay, mSurface, 260 b.left, b.top, b.width(), b.height()); 261 } 262 } 263 264 mPageFlipCount++; 265 } 266 267 status_t DisplayDevice::beginFrame(bool mustRecompose) const { 268 return mDisplaySurface->beginFrame(mustRecompose); 269 } 270 271 #ifdef USE_HWC2 272 status_t DisplayDevice::prepareFrame(HWComposer& hwc) { 273 status_t error = hwc.prepare(*this); 274 if (error != NO_ERROR) { 275 return error; 276 } 277 278 DisplaySurface::CompositionType compositionType; 279 bool hasClient = hwc.hasClientComposition(mHwcDisplayId); 280 bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId); 281 if (hasClient && hasDevice) { 282 compositionType = DisplaySurface::COMPOSITION_MIXED; 283 } else if (hasClient) { 284 compositionType = DisplaySurface::COMPOSITION_GLES; 285 } else if (hasDevice) { 286 compositionType = DisplaySurface::COMPOSITION_HWC; 287 } else { 288 // Nothing to do -- when turning the screen off we get a frame like 289 // this. Call it a HWC frame since we won't be doing any GLES work but 290 // will do a prepare/set cycle. 291 compositionType = DisplaySurface::COMPOSITION_HWC; 292 } 293 return mDisplaySurface->prepareFrame(compositionType); 294 } 295 #else 296 status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const { 297 DisplaySurface::CompositionType compositionType; 298 bool haveGles = hwc.hasGlesComposition(mHwcDisplayId); 299 bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId); 300 if (haveGles && haveHwc) { 301 compositionType = DisplaySurface::COMPOSITION_MIXED; 302 } else if (haveGles) { 303 compositionType = DisplaySurface::COMPOSITION_GLES; 304 } else if (haveHwc) { 305 compositionType = DisplaySurface::COMPOSITION_HWC; 306 } else { 307 // Nothing to do -- when turning the screen off we get a frame like 308 // this. Call it a HWC frame since we won't be doing any GLES work but 309 // will do a prepare/set cycle. 310 compositionType = DisplaySurface::COMPOSITION_HWC; 311 } 312 return mDisplaySurface->prepareFrame(compositionType); 313 } 314 #endif 315 316 void DisplayDevice::swapBuffers(HWComposer& hwc) const { 317 #ifdef USE_HWC2 318 if (hwc.hasClientComposition(mHwcDisplayId)) { 319 #else 320 // We need to call eglSwapBuffers() if: 321 // (1) we don't have a hardware composer, or 322 // (2) we did GLES composition this frame, and either 323 // (a) we have framebuffer target support (not present on legacy 324 // devices, where HWComposer::commit() handles things); or 325 // (b) this is a virtual display 326 if (hwc.initCheck() != NO_ERROR || 327 (hwc.hasGlesComposition(mHwcDisplayId) && 328 (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) { 329 #endif 330 EGLBoolean success = eglSwapBuffers(mDisplay, mSurface); 331 if (!success) { 332 EGLint error = eglGetError(); 333 if (error == EGL_CONTEXT_LOST || 334 mType == DisplayDevice::DISPLAY_PRIMARY) { 335 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x", 336 mDisplay, mSurface, error); 337 } else { 338 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x", 339 mDisplay, mSurface, error); 340 } 341 } 342 } 343 344 status_t result = mDisplaySurface->advanceFrame(); 345 if (result != NO_ERROR) { 346 ALOGE("[%s] failed pushing new frame to HWC: %d", 347 mDisplayName.string(), result); 348 } 349 } 350 351 #ifdef USE_HWC2 352 void DisplayDevice::onSwapBuffersCompleted() const { 353 mDisplaySurface->onFrameCommitted(); 354 } 355 #else 356 void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const { 357 if (hwc.initCheck() == NO_ERROR) { 358 mDisplaySurface->onFrameCommitted(); 359 } 360 } 361 #endif 362 363 uint32_t DisplayDevice::getFlags() const 364 { 365 return mFlags; 366 } 367 368 EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const { 369 EGLBoolean result = EGL_TRUE; 370 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 371 if (sur != mSurface) { 372 result = eglMakeCurrent(dpy, mSurface, mSurface, ctx); 373 if (result == EGL_TRUE) { 374 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 375 eglSwapInterval(dpy, 0); 376 } 377 } 378 setViewportAndProjection(); 379 return result; 380 } 381 382 void DisplayDevice::setViewportAndProjection() const { 383 size_t w = mDisplayWidth; 384 size_t h = mDisplayHeight; 385 Rect sourceCrop(0, 0, w, h); 386 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, 387 false, Transform::ROT_0); 388 } 389 390 const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const { 391 return mDisplaySurface->getClientTargetAcquireFence(); 392 } 393 394 // ---------------------------------------------------------------------------- 395 396 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { 397 mVisibleLayersSortedByZ = layers; 398 } 399 400 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { 401 return mVisibleLayersSortedByZ; 402 } 403 404 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 405 Region dirty; 406 if (repaintEverything) { 407 dirty.set(getBounds()); 408 } else { 409 const Transform& planeTransform(mGlobalTransform); 410 dirty = planeTransform.transform(this->dirtyRegion); 411 dirty.andSelf(getBounds()); 412 } 413 return dirty; 414 } 415 416 // ---------------------------------------------------------------------------- 417 void DisplayDevice::setPowerMode(int mode) { 418 mPowerMode = mode; 419 } 420 421 int DisplayDevice::getPowerMode() const { 422 return mPowerMode; 423 } 424 425 bool DisplayDevice::isDisplayOn() const { 426 return (mPowerMode != HWC_POWER_MODE_OFF); 427 } 428 429 // ---------------------------------------------------------------------------- 430 void DisplayDevice::setActiveConfig(int mode) { 431 mActiveConfig = mode; 432 } 433 434 int DisplayDevice::getActiveConfig() const { 435 return mActiveConfig; 436 } 437 438 // ---------------------------------------------------------------------------- 439 #ifdef USE_HWC2 440 void DisplayDevice::setActiveColorMode(android_color_mode_t mode) { 441 mActiveColorMode = mode; 442 } 443 444 android_color_mode_t DisplayDevice::getActiveColorMode() const { 445 return mActiveColorMode; 446 } 447 448 void DisplayDevice::setCompositionDataSpace(android_dataspace dataspace) { 449 ANativeWindow* const window = mNativeWindow.get(); 450 native_window_set_buffers_data_space(window, dataspace); 451 } 452 #endif 453 454 // ---------------------------------------------------------------------------- 455 456 void DisplayDevice::setLayerStack(uint32_t stack) { 457 mLayerStack = stack; 458 dirtyRegion.set(bounds()); 459 } 460 461 // ---------------------------------------------------------------------------- 462 463 uint32_t DisplayDevice::getOrientationTransform() const { 464 uint32_t transform = 0; 465 switch (mOrientation) { 466 case DisplayState::eOrientationDefault: 467 transform = Transform::ROT_0; 468 break; 469 case DisplayState::eOrientation90: 470 transform = Transform::ROT_90; 471 break; 472 case DisplayState::eOrientation180: 473 transform = Transform::ROT_180; 474 break; 475 case DisplayState::eOrientation270: 476 transform = Transform::ROT_270; 477 break; 478 } 479 return transform; 480 } 481 482 status_t DisplayDevice::orientationToTransfrom( 483 int orientation, int w, int h, Transform* tr) 484 { 485 uint32_t flags = 0; 486 switch (orientation) { 487 case DisplayState::eOrientationDefault: 488 flags = Transform::ROT_0; 489 break; 490 case DisplayState::eOrientation90: 491 flags = Transform::ROT_90; 492 break; 493 case DisplayState::eOrientation180: 494 flags = Transform::ROT_180; 495 break; 496 case DisplayState::eOrientation270: 497 flags = Transform::ROT_270; 498 break; 499 default: 500 return BAD_VALUE; 501 } 502 tr->set(flags, w, h); 503 return NO_ERROR; 504 } 505 506 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) { 507 dirtyRegion.set(getBounds()); 508 509 if (mSurface != EGL_NO_SURFACE) { 510 eglDestroySurface(mDisplay, mSurface); 511 mSurface = EGL_NO_SURFACE; 512 } 513 514 mDisplaySurface->resizeBuffers(newWidth, newHeight); 515 516 ANativeWindow* const window = mNativeWindow.get(); 517 mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL); 518 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth); 519 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight); 520 521 LOG_FATAL_IF(mDisplayWidth != newWidth, 522 "Unable to set new width to %d", newWidth); 523 LOG_FATAL_IF(mDisplayHeight != newHeight, 524 "Unable to set new height to %d", newHeight); 525 } 526 527 void DisplayDevice::setProjection(int orientation, 528 const Rect& newViewport, const Rect& newFrame) { 529 Rect viewport(newViewport); 530 Rect frame(newFrame); 531 532 const int w = mDisplayWidth; 533 const int h = mDisplayHeight; 534 535 Transform R; 536 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 537 538 if (!frame.isValid()) { 539 // the destination frame can be invalid if it has never been set, 540 // in that case we assume the whole display frame. 541 frame = Rect(w, h); 542 } 543 544 if (viewport.isEmpty()) { 545 // viewport can be invalid if it has never been set, in that case 546 // we assume the whole display size. 547 // it's also invalid to have an empty viewport, so we handle that 548 // case in the same way. 549 viewport = Rect(w, h); 550 if (R.getOrientation() & Transform::ROT_90) { 551 // viewport is always specified in the logical orientation 552 // of the display (ie: post-rotation). 553 swap(viewport.right, viewport.bottom); 554 } 555 } 556 557 dirtyRegion.set(getBounds()); 558 559 Transform TL, TP, S; 560 float src_width = viewport.width(); 561 float src_height = viewport.height(); 562 float dst_width = frame.width(); 563 float dst_height = frame.height(); 564 if (src_width != dst_width || src_height != dst_height) { 565 float sx = dst_width / src_width; 566 float sy = dst_height / src_height; 567 S.set(sx, 0, 0, sy); 568 } 569 570 float src_x = viewport.left; 571 float src_y = viewport.top; 572 float dst_x = frame.left; 573 float dst_y = frame.top; 574 TL.set(-src_x, -src_y); 575 TP.set(dst_x, dst_y); 576 577 // The viewport and frame are both in the logical orientation. 578 // Apply the logical translation, scale to physical size, apply the 579 // physical translation and finally rotate to the physical orientation. 580 mGlobalTransform = R * TP * S * TL; 581 582 const uint8_t type = mGlobalTransform.getType(); 583 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 584 (type >= Transform::SCALE)); 585 586 mScissor = mGlobalTransform.transform(viewport); 587 if (mScissor.isEmpty()) { 588 mScissor = getBounds(); 589 } 590 591 mOrientation = orientation; 592 if (mType == DisplayType::DISPLAY_PRIMARY) { 593 uint32_t transform = 0; 594 switch (mOrientation) { 595 case DisplayState::eOrientationDefault: 596 transform = Transform::ROT_0; 597 break; 598 case DisplayState::eOrientation90: 599 transform = Transform::ROT_90; 600 break; 601 case DisplayState::eOrientation180: 602 transform = Transform::ROT_180; 603 break; 604 case DisplayState::eOrientation270: 605 transform = Transform::ROT_270; 606 break; 607 } 608 sPrimaryDisplayOrientation = transform; 609 } 610 mViewport = viewport; 611 mFrame = frame; 612 } 613 614 uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() { 615 return sPrimaryDisplayOrientation; 616 } 617 618 void DisplayDevice::dump(String8& result) const { 619 const Transform& tr(mGlobalTransform); 620 EGLint redSize, greenSize, blueSize, alphaSize; 621 eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &redSize); 622 eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &greenSize); 623 eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &blueSize); 624 eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &alphaSize); 625 result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string()); 626 result.appendFormat(" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p " 627 "(%d:%d:%d:%d), orient=%2d (type=%08x), " 628 "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n", 629 mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, 630 mNativeWindow.get(), redSize, greenSize, blueSize, alphaSize, mOrientation, 631 tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig, 632 mVisibleLayersSortedByZ.size()); 633 result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 634 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 635 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 636 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, mScissor.left, 637 mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0], 638 tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]); 639 640 String8 surfaceDump; 641 mDisplaySurface->dumpAsString(surfaceDump); 642 result.append(surfaceDump); 643 } 644 645 std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1); 646 647 DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure) 648 : type(type), 649 layerStack(DisplayDevice::NO_LAYER_STACK), 650 orientation(0), 651 width(0), 652 height(0), 653 isSecure(isSecure) 654 { 655 viewport.makeInvalid(); 656 frame.makeInvalid(); 657 } 658