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