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