DisplayDevice.cpp revision d4548dd0272f5a4edee1d7ff070458728848b35c
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/* 48 * Initialize the display to the specified values. 49 * 50 */ 51 52DisplayDevice::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 136DisplayDevice::~DisplayDevice() { 137 if (mSurface != EGL_NO_SURFACE) { 138 eglDestroySurface(mDisplay, mSurface); 139 mSurface = EGL_NO_SURFACE; 140 } 141} 142 143void 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 152bool DisplayDevice::isValid() const { 153 return mFlinger != NULL; 154} 155 156int DisplayDevice::getWidth() const { 157 return mDisplayWidth; 158} 159 160int DisplayDevice::getHeight() const { 161 return mDisplayHeight; 162} 163 164PixelFormat DisplayDevice::getFormat() const { 165 return mFormat; 166} 167 168EGLSurface DisplayDevice::getEGLSurface() const { 169 return mSurface; 170} 171 172void DisplayDevice::setDisplayName(const String8& displayName) { 173 if (!displayName.isEmpty()) { 174 // never override the name with an empty name 175 mDisplayName = displayName; 176 } 177} 178 179uint32_t DisplayDevice::getPageFlipCount() const { 180 return mPageFlipCount; 181} 182 183status_t DisplayDevice::compositionComplete() const { 184 return mDisplaySurface->compositionComplete(); 185} 186 187void 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 208status_t DisplayDevice::beginFrame(bool mustRecompose) const { 209 return mDisplaySurface->beginFrame(mustRecompose); 210} 211 212status_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 231void 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 262void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const { 263 if (hwc.initCheck() == NO_ERROR) { 264 mDisplaySurface->onFrameCommitted(); 265 } 266} 267 268uint32_t DisplayDevice::getFlags() const 269{ 270 return mFlags; 271} 272 273EGLBoolean 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 287void 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, false); 292} 293 294// ---------------------------------------------------------------------------- 295 296void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { 297 mVisibleLayersSortedByZ = layers; 298 mSecureLayerVisible = false; 299 size_t count = layers.size(); 300 for (size_t i=0 ; i<count ; i++) { 301 const sp<Layer>& layer(layers[i]); 302 if (layer->isSecure()) { 303 mSecureLayerVisible = true; 304 } 305 } 306} 307 308const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { 309 return mVisibleLayersSortedByZ; 310} 311 312bool DisplayDevice::getSecureLayerVisible() const { 313 return mSecureLayerVisible; 314} 315 316Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 317 Region dirty; 318 if (repaintEverything) { 319 dirty.set(getBounds()); 320 } else { 321 const Transform& planeTransform(mGlobalTransform); 322 dirty = planeTransform.transform(this->dirtyRegion); 323 dirty.andSelf(getBounds()); 324 } 325 return dirty; 326} 327 328// ---------------------------------------------------------------------------- 329void DisplayDevice::setPowerMode(int mode) { 330 mPowerMode = mode; 331} 332 333int DisplayDevice::getPowerMode() const { 334 return mPowerMode; 335} 336 337bool DisplayDevice::isDisplayOn() const { 338 return (mPowerMode != HWC_POWER_MODE_OFF); 339} 340 341// ---------------------------------------------------------------------------- 342void DisplayDevice::setActiveConfig(int mode) { 343 mActiveConfig = mode; 344} 345 346int DisplayDevice::getActiveConfig() const { 347 return mActiveConfig; 348} 349 350// ---------------------------------------------------------------------------- 351 352void DisplayDevice::setLayerStack(uint32_t stack) { 353 mLayerStack = stack; 354 dirtyRegion.set(bounds()); 355} 356 357// ---------------------------------------------------------------------------- 358 359uint32_t DisplayDevice::getOrientationTransform() const { 360 uint32_t transform = 0; 361 switch (mOrientation) { 362 case DisplayState::eOrientationDefault: 363 transform = Transform::ROT_0; 364 break; 365 case DisplayState::eOrientation90: 366 transform = Transform::ROT_90; 367 break; 368 case DisplayState::eOrientation180: 369 transform = Transform::ROT_180; 370 break; 371 case DisplayState::eOrientation270: 372 transform = Transform::ROT_270; 373 break; 374 } 375 return transform; 376} 377 378status_t DisplayDevice::orientationToTransfrom( 379 int orientation, int w, int h, Transform* tr) 380{ 381 uint32_t flags = 0; 382 switch (orientation) { 383 case DisplayState::eOrientationDefault: 384 flags = Transform::ROT_0; 385 break; 386 case DisplayState::eOrientation90: 387 flags = Transform::ROT_90; 388 break; 389 case DisplayState::eOrientation180: 390 flags = Transform::ROT_180; 391 break; 392 case DisplayState::eOrientation270: 393 flags = Transform::ROT_270; 394 break; 395 default: 396 return BAD_VALUE; 397 } 398 tr->set(flags, w, h); 399 return NO_ERROR; 400} 401 402void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) { 403 dirtyRegion.set(getBounds()); 404 405 if (mSurface != EGL_NO_SURFACE) { 406 eglDestroySurface(mDisplay, mSurface); 407 mSurface = EGL_NO_SURFACE; 408 } 409 410 mDisplaySurface->resizeBuffers(newWidth, newHeight); 411 412 ANativeWindow* const window = mNativeWindow.get(); 413 mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL); 414 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth); 415 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight); 416 417 LOG_FATAL_IF(mDisplayWidth != newWidth, 418 "Unable to set new width to %d", newWidth); 419 LOG_FATAL_IF(mDisplayHeight != newHeight, 420 "Unable to set new height to %d", newHeight); 421} 422 423void DisplayDevice::setProjection(int orientation, 424 const Rect& newViewport, const Rect& newFrame) { 425 Rect viewport(newViewport); 426 Rect frame(newFrame); 427 428 const int w = mDisplayWidth; 429 const int h = mDisplayHeight; 430 431 Transform R; 432 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 433 434 if (!frame.isValid()) { 435 // the destination frame can be invalid if it has never been set, 436 // in that case we assume the whole display frame. 437 frame = Rect(w, h); 438 } 439 440 if (viewport.isEmpty()) { 441 // viewport can be invalid if it has never been set, in that case 442 // we assume the whole display size. 443 // it's also invalid to have an empty viewport, so we handle that 444 // case in the same way. 445 viewport = Rect(w, h); 446 if (R.getOrientation() & Transform::ROT_90) { 447 // viewport is always specified in the logical orientation 448 // of the display (ie: post-rotation). 449 swap(viewport.right, viewport.bottom); 450 } 451 } 452 453 dirtyRegion.set(getBounds()); 454 455 Transform TL, TP, S; 456 float src_width = viewport.width(); 457 float src_height = viewport.height(); 458 float dst_width = frame.width(); 459 float dst_height = frame.height(); 460 if (src_width != dst_width || src_height != dst_height) { 461 float sx = dst_width / src_width; 462 float sy = dst_height / src_height; 463 S.set(sx, 0, 0, sy); 464 } 465 466 float src_x = viewport.left; 467 float src_y = viewport.top; 468 float dst_x = frame.left; 469 float dst_y = frame.top; 470 TL.set(-src_x, -src_y); 471 TP.set(dst_x, dst_y); 472 473 // The viewport and frame are both in the logical orientation. 474 // Apply the logical translation, scale to physical size, apply the 475 // physical translation and finally rotate to the physical orientation. 476 mGlobalTransform = R * TP * S * TL; 477 478 const uint8_t type = mGlobalTransform.getType(); 479 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 480 (type >= Transform::SCALE)); 481 482 mScissor = mGlobalTransform.transform(viewport); 483 if (mScissor.isEmpty()) { 484 mScissor = getBounds(); 485 } 486 487 mOrientation = orientation; 488 mViewport = viewport; 489 mFrame = frame; 490} 491 492void DisplayDevice::dump(String8& result) const { 493 const Transform& tr(mGlobalTransform); 494 result.appendFormat( 495 "+ DisplayDevice: %s\n" 496 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), " 497 "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n" 498 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 499 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 500 mDisplayName.string(), mType, mHwcDisplayId, 501 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(), 502 mOrientation, tr.getType(), getPageFlipCount(), 503 mIsSecure, mSecureLayerVisible, mPowerMode, mActiveConfig, 504 mVisibleLayersSortedByZ.size(), 505 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 506 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, 507 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom, 508 tr[0][0], tr[1][0], tr[2][0], 509 tr[0][1], tr[1][1], tr[2][1], 510 tr[0][2], tr[1][2], tr[2][2]); 511 512 String8 surfaceDump; 513 mDisplaySurface->dump(surfaceDump); 514 result.append(surfaceDump); 515} 516