DisplayDevice.cpp revision 47e45405d1533aa73307014f7bf371e118695cf3
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 mDisplaySurface->resizeBuffers(newWidth, newHeight); 405 406 ANativeWindow* const window = mNativeWindow.get(); 407 mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL); 408 eglQuerySurface(mDisplay, mSurface, EGL_WIDTH, &mDisplayWidth); 409 eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight); 410 411 LOG_FATAL_IF(mDisplayWidth != newWidth, 412 "Unable to set new width to %d", newWidth); 413 LOG_FATAL_IF(mDisplayHeight != newHeight, 414 "Unable to set new height to %d", newHeight); 415} 416 417void DisplayDevice::setProjection(int orientation, 418 const Rect& newViewport, const Rect& newFrame) { 419 Rect viewport(newViewport); 420 Rect frame(newFrame); 421 422 const int w = mDisplayWidth; 423 const int h = mDisplayHeight; 424 425 Transform R; 426 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 427 428 if (!frame.isValid()) { 429 // the destination frame can be invalid if it has never been set, 430 // in that case we assume the whole display frame. 431 frame = Rect(w, h); 432 } 433 434 if (viewport.isEmpty()) { 435 // viewport can be invalid if it has never been set, in that case 436 // we assume the whole display size. 437 // it's also invalid to have an empty viewport, so we handle that 438 // case in the same way. 439 viewport = Rect(w, h); 440 if (R.getOrientation() & Transform::ROT_90) { 441 // viewport is always specified in the logical orientation 442 // of the display (ie: post-rotation). 443 swap(viewport.right, viewport.bottom); 444 } 445 } 446 447 dirtyRegion.set(getBounds()); 448 449 Transform TL, TP, S; 450 float src_width = viewport.width(); 451 float src_height = viewport.height(); 452 float dst_width = frame.width(); 453 float dst_height = frame.height(); 454 if (src_width != dst_width || src_height != dst_height) { 455 float sx = dst_width / src_width; 456 float sy = dst_height / src_height; 457 S.set(sx, 0, 0, sy); 458 } 459 460 float src_x = viewport.left; 461 float src_y = viewport.top; 462 float dst_x = frame.left; 463 float dst_y = frame.top; 464 TL.set(-src_x, -src_y); 465 TP.set(dst_x, dst_y); 466 467 // The viewport and frame are both in the logical orientation. 468 // Apply the logical translation, scale to physical size, apply the 469 // physical translation and finally rotate to the physical orientation. 470 mGlobalTransform = R * TP * S * TL; 471 472 const uint8_t type = mGlobalTransform.getType(); 473 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 474 (type >= Transform::SCALE)); 475 476 mScissor = mGlobalTransform.transform(viewport); 477 if (mScissor.isEmpty()) { 478 mScissor = getBounds(); 479 } 480 481 mOrientation = orientation; 482 mViewport = viewport; 483 mFrame = frame; 484} 485 486void DisplayDevice::dump(String8& result) const { 487 const Transform& tr(mGlobalTransform); 488 result.appendFormat( 489 "+ DisplayDevice: %s\n" 490 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), " 491 "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n" 492 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 493 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 494 mDisplayName.string(), mType, mHwcDisplayId, 495 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(), 496 mOrientation, tr.getType(), getPageFlipCount(), 497 mIsSecure, mSecureLayerVisible, mPowerMode, mActiveConfig, 498 mVisibleLayersSortedByZ.size(), 499 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 500 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, 501 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom, 502 tr[0][0], tr[1][0], tr[2][0], 503 tr[0][1], tr[1][1], tr[2][1], 504 tr[0][2], tr[1][2], tr[2][2]); 505 506 String8 surfaceDump; 507 mDisplaySurface->dump(surfaceDump); 508 result.append(surfaceDump); 509} 510