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