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