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