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