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#include <stdlib.h> 18#include <stdio.h> 19#include <string.h> 20#include <math.h> 21 22#include <cutils/properties.h> 23 24#include <utils/RefBase.h> 25#include <utils/Log.h> 26 27#include <ui/DisplayInfo.h> 28#include <ui/PixelFormat.h> 29 30#include <gui/Surface.h> 31 32#include <hardware/gralloc.h> 33 34#include "DisplayHardware/DisplaySurface.h" 35#include "DisplayHardware/HWComposer.h" 36#include "RenderEngine/RenderEngine.h" 37 38#include "clz.h" 39#include "DisplayDevice.h" 40#include "SurfaceFlinger.h" 41#include "Layer.h" 42 43// ---------------------------------------------------------------------------- 44using namespace android; 45// ---------------------------------------------------------------------------- 46 47#ifdef EGL_ANDROID_swap_rectangle 48static constexpr bool kEGLAndroidSwapRectangle = true; 49#else 50static constexpr bool kEGLAndroidSwapRectangle = false; 51#endif 52 53#if !defined(EGL_EGLEXT_PROTOTYPES) || !defined(EGL_ANDROID_swap_rectangle) 54// Dummy implementation in case it is missing. 55inline void eglSetSwapRectangleANDROID (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) { 56} 57#endif 58 59/* 60 * Initialize the display to the specified values. 61 * 62 */ 63 64DisplayDevice::DisplayDevice( 65 const sp<SurfaceFlinger>& flinger, 66 DisplayType type, 67 int32_t hwcId, 68 int format, 69 bool isSecure, 70 const wp<IBinder>& displayToken, 71 const sp<DisplaySurface>& displaySurface, 72 const sp<IGraphicBufferProducer>& producer, 73 EGLConfig config) 74 : lastCompositionHadVisibleLayers(false), 75 mFlinger(flinger), 76 mType(type), mHwcDisplayId(hwcId), 77 mDisplayToken(displayToken), 78 mDisplaySurface(displaySurface), 79 mDisplay(EGL_NO_DISPLAY), 80 mSurface(EGL_NO_SURFACE), 81 mDisplayWidth(), mDisplayHeight(), mFormat(), 82 mFlags(), 83 mPageFlipCount(), 84 mIsSecure(isSecure), 85 mSecureLayerVisible(false), 86 mLayerStack(NO_LAYER_STACK), 87 mOrientation(), 88 mPowerMode(HWC_POWER_MODE_OFF), 89 mActiveConfig(0) 90{ 91 mNativeWindow = new Surface(producer, false); 92 ANativeWindow* const window = mNativeWindow.get(); 93 94 /* 95 * Create our display's surface 96 */ 97 98 EGLSurface surface; 99 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 100 if (config == EGL_NO_CONFIG) { 101 config = RenderEngine::chooseEglConfig(display, format); 102 } 103 surface = eglCreateWindowSurface(display, config, window, NULL); 104 eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth); 105 eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight); 106 107 // Make sure that composition can never be stalled by a virtual display 108 // consumer that isn't processing buffers fast enough. We have to do this 109 // in two places: 110 // * Here, in case the display is composed entirely by HWC. 111 // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the 112 // window's swap interval in eglMakeCurrent, so they'll override the 113 // interval we set here. 114 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 115 window->setSwapInterval(window, 0); 116 117 mConfig = config; 118 mDisplay = display; 119 mSurface = surface; 120 mFormat = format; 121 mPageFlipCount = 0; 122 mViewport.makeInvalid(); 123 mFrame.makeInvalid(); 124 125 // virtual displays are always considered enabled 126 mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ? 127 HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF; 128 129 // Name the display. The name will be replaced shortly if the display 130 // was created with createDisplay(). 131 switch (mType) { 132 case DISPLAY_PRIMARY: 133 mDisplayName = "Built-in Screen"; 134 break; 135 case DISPLAY_EXTERNAL: 136 mDisplayName = "HDMI Screen"; 137 break; 138 default: 139 mDisplayName = "Virtual Screen"; // e.g. Overlay #n 140 break; 141 } 142 143 // initialize the display orientation transform. 144 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame); 145} 146 147DisplayDevice::~DisplayDevice() { 148 if (mSurface != EGL_NO_SURFACE) { 149 eglDestroySurface(mDisplay, mSurface); 150 mSurface = EGL_NO_SURFACE; 151 } 152} 153 154void DisplayDevice::disconnect(HWComposer& hwc) { 155 if (mHwcDisplayId >= 0) { 156 hwc.disconnectDisplay(mHwcDisplayId); 157 if (mHwcDisplayId >= DISPLAY_VIRTUAL) 158 hwc.freeDisplayId(mHwcDisplayId); 159 mHwcDisplayId = -1; 160 } 161} 162 163bool DisplayDevice::isValid() const { 164 return mFlinger != NULL; 165} 166 167int DisplayDevice::getWidth() const { 168 return mDisplayWidth; 169} 170 171int DisplayDevice::getHeight() const { 172 return mDisplayHeight; 173} 174 175PixelFormat DisplayDevice::getFormat() const { 176 return mFormat; 177} 178 179EGLSurface DisplayDevice::getEGLSurface() const { 180 return mSurface; 181} 182 183void DisplayDevice::setDisplayName(const String8& displayName) { 184 if (!displayName.isEmpty()) { 185 // never override the name with an empty name 186 mDisplayName = displayName; 187 } 188} 189 190uint32_t DisplayDevice::getPageFlipCount() const { 191 return mPageFlipCount; 192} 193 194status_t DisplayDevice::compositionComplete() const { 195 return mDisplaySurface->compositionComplete(); 196} 197 198void DisplayDevice::flip(const Region& dirty) const 199{ 200 mFlinger->getRenderEngine().checkErrors(); 201 202 if (kEGLAndroidSwapRectangle) { 203 if (mFlags & SWAP_RECTANGLE) { 204 const Region newDirty(dirty.intersect(bounds())); 205 const Rect b(newDirty.getBounds()); 206 eglSetSwapRectangleANDROID(mDisplay, mSurface, 207 b.left, b.top, b.width(), b.height()); 208 } 209 } 210 211 mPageFlipCount++; 212} 213 214status_t DisplayDevice::beginFrame(bool mustRecompose) const { 215 return mDisplaySurface->beginFrame(mustRecompose); 216} 217 218status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const { 219 DisplaySurface::CompositionType compositionType; 220 bool haveGles = hwc.hasGlesComposition(mHwcDisplayId); 221 bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId); 222 if (haveGles && haveHwc) { 223 compositionType = DisplaySurface::COMPOSITION_MIXED; 224 } else if (haveGles) { 225 compositionType = DisplaySurface::COMPOSITION_GLES; 226 } else if (haveHwc) { 227 compositionType = DisplaySurface::COMPOSITION_HWC; 228 } else { 229 // Nothing to do -- when turning the screen off we get a frame like 230 // this. Call it a HWC frame since we won't be doing any GLES work but 231 // will do a prepare/set cycle. 232 compositionType = DisplaySurface::COMPOSITION_HWC; 233 } 234 return mDisplaySurface->prepareFrame(compositionType); 235} 236 237void DisplayDevice::swapBuffers(HWComposer& hwc) const { 238 // We need to call eglSwapBuffers() if: 239 // (1) we don't have a hardware composer, or 240 // (2) we did GLES composition this frame, and either 241 // (a) we have framebuffer target support (not present on legacy 242 // devices, where HWComposer::commit() handles things); or 243 // (b) this is a virtual display 244 if (hwc.initCheck() != NO_ERROR || 245 (hwc.hasGlesComposition(mHwcDisplayId) && 246 (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) { 247 EGLBoolean success = eglSwapBuffers(mDisplay, mSurface); 248 if (!success) { 249 EGLint error = eglGetError(); 250 if (error == EGL_CONTEXT_LOST || 251 mType == DisplayDevice::DISPLAY_PRIMARY) { 252 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x", 253 mDisplay, mSurface, error); 254 } else { 255 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x", 256 mDisplay, mSurface, error); 257 } 258 } 259 } 260 261 status_t result = mDisplaySurface->advanceFrame(); 262 if (result != NO_ERROR) { 263 ALOGE("[%s] failed pushing new frame to HWC: %d", 264 mDisplayName.string(), result); 265 } 266} 267 268void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const { 269 if (hwc.initCheck() == NO_ERROR) { 270 mDisplaySurface->onFrameCommitted(); 271 } 272} 273 274uint32_t DisplayDevice::getFlags() const 275{ 276 return mFlags; 277} 278 279EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const { 280 EGLBoolean result = EGL_TRUE; 281 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 282 if (sur != mSurface) { 283 result = eglMakeCurrent(dpy, mSurface, mSurface, ctx); 284 if (result == EGL_TRUE) { 285 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 286 eglSwapInterval(dpy, 0); 287 } 288 } 289 setViewportAndProjection(); 290 return result; 291} 292 293void DisplayDevice::setViewportAndProjection() const { 294 size_t w = mDisplayWidth; 295 size_t h = mDisplayHeight; 296 Rect sourceCrop(0, 0, w, h); 297 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, 298 false, Transform::ROT_0); 299} 300 301// ---------------------------------------------------------------------------- 302 303void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { 304 mVisibleLayersSortedByZ = layers; 305 mSecureLayerVisible = false; 306 size_t count = layers.size(); 307 for (size_t i=0 ; i<count ; i++) { 308 const sp<Layer>& layer(layers[i]); 309 if (layer->isSecure()) { 310 mSecureLayerVisible = true; 311 } 312 } 313} 314 315const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { 316 return mVisibleLayersSortedByZ; 317} 318 319bool DisplayDevice::getSecureLayerVisible() const { 320 return mSecureLayerVisible; 321} 322 323Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 324 Region dirty; 325 if (repaintEverything) { 326 dirty.set(getBounds()); 327 } else { 328 const Transform& planeTransform(mGlobalTransform); 329 dirty = planeTransform.transform(this->dirtyRegion); 330 dirty.andSelf(getBounds()); 331 } 332 return dirty; 333} 334 335// ---------------------------------------------------------------------------- 336void DisplayDevice::setPowerMode(int mode) { 337 mPowerMode = mode; 338} 339 340int DisplayDevice::getPowerMode() const { 341 return mPowerMode; 342} 343 344bool DisplayDevice::isDisplayOn() const { 345 return (mPowerMode != HWC_POWER_MODE_OFF); 346} 347 348// ---------------------------------------------------------------------------- 349void DisplayDevice::setActiveConfig(int mode) { 350 mActiveConfig = mode; 351} 352 353int DisplayDevice::getActiveConfig() const { 354 return mActiveConfig; 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 mViewport = viewport; 496 mFrame = frame; 497} 498 499void DisplayDevice::dump(String8& result) const { 500 const Transform& tr(mGlobalTransform); 501 result.appendFormat( 502 "+ DisplayDevice: %s\n" 503 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), " 504 "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n" 505 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 506 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 507 mDisplayName.string(), mType, mHwcDisplayId, 508 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(), 509 mOrientation, tr.getType(), getPageFlipCount(), 510 mIsSecure, mSecureLayerVisible, mPowerMode, mActiveConfig, 511 mVisibleLayersSortedByZ.size(), 512 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 513 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, 514 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom, 515 tr[0][0], tr[1][0], tr[2][0], 516 tr[0][1], tr[1][1], tr[2][1], 517 tr[0][2], tr[1][2], tr[2][2]); 518 519 String8 surfaceDump; 520 mDisplaySurface->dumpAsString(surfaceDump); 521 result.append(surfaceDump); 522} 523