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