DisplayDevice.cpp revision c18790018be5d7ea7061ccbc81f3044e74adc823
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 /* 81 * Create our display's surface 82 */ 83 84 EGLSurface surface; 85 EGLint w, h; 86 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 87 if (config == EGL_NO_CONFIG) { 88 config = RenderEngine::chooseEglConfig(display, format); 89 } 90 surface = eglCreateWindowSurface(display, config, window, NULL); 91 eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth); 92 eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight); 93 94 // Make sure that composition can never be stalled by a virtual display 95 // consumer that isn't processing buffers fast enough. We have to do this 96 // in two places: 97 // * Here, in case the display is composed entirely by HWC. 98 // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the 99 // window's swap interval in eglMakeCurrent, so they'll override the 100 // interval we set here. 101 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 102 window->setSwapInterval(window, 0); 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 Rect sourceCrop(0, 0, w, h); 287 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, false); 288} 289 290// ---------------------------------------------------------------------------- 291 292void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { 293 mVisibleLayersSortedByZ = layers; 294 mSecureLayerVisible = false; 295 size_t count = layers.size(); 296 for (size_t i=0 ; i<count ; i++) { 297 const sp<Layer>& layer(layers[i]); 298 if (layer->isSecure()) { 299 mSecureLayerVisible = true; 300 } 301 } 302} 303 304const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { 305 return mVisibleLayersSortedByZ; 306} 307 308bool DisplayDevice::getSecureLayerVisible() const { 309 return mSecureLayerVisible; 310} 311 312Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 313 Region dirty; 314 if (repaintEverything) { 315 dirty.set(getBounds()); 316 } else { 317 const Transform& planeTransform(mGlobalTransform); 318 dirty = planeTransform.transform(this->dirtyRegion); 319 dirty.andSelf(getBounds()); 320 } 321 return dirty; 322} 323 324// ---------------------------------------------------------------------------- 325 326bool DisplayDevice::canDraw() const { 327 return mScreenAcquired; 328} 329 330void DisplayDevice::releaseScreen() const { 331 mScreenAcquired = false; 332} 333 334void DisplayDevice::acquireScreen() const { 335 mScreenAcquired = true; 336} 337 338bool DisplayDevice::isScreenAcquired() const { 339 return mScreenAcquired; 340} 341 342// ---------------------------------------------------------------------------- 343 344void DisplayDevice::setLayerStack(uint32_t stack) { 345 mLayerStack = stack; 346 dirtyRegion.set(bounds()); 347} 348 349// ---------------------------------------------------------------------------- 350 351uint32_t DisplayDevice::getOrientationTransform() const { 352 uint32_t transform = 0; 353 switch (mOrientation) { 354 case DisplayState::eOrientationDefault: 355 transform = Transform::ROT_0; 356 break; 357 case DisplayState::eOrientation90: 358 transform = Transform::ROT_90; 359 break; 360 case DisplayState::eOrientation180: 361 transform = Transform::ROT_180; 362 break; 363 case DisplayState::eOrientation270: 364 transform = Transform::ROT_270; 365 break; 366 } 367 return transform; 368} 369 370status_t DisplayDevice::orientationToTransfrom( 371 int orientation, int w, int h, Transform* tr) 372{ 373 uint32_t flags = 0; 374 switch (orientation) { 375 case DisplayState::eOrientationDefault: 376 flags = Transform::ROT_0; 377 break; 378 case DisplayState::eOrientation90: 379 flags = Transform::ROT_90; 380 break; 381 case DisplayState::eOrientation180: 382 flags = Transform::ROT_180; 383 break; 384 case DisplayState::eOrientation270: 385 flags = Transform::ROT_270; 386 break; 387 default: 388 return BAD_VALUE; 389 } 390 tr->set(flags, w, h); 391 return NO_ERROR; 392} 393 394void DisplayDevice::setProjection(int orientation, 395 const Rect& newViewport, const Rect& newFrame) { 396 Rect viewport(newViewport); 397 Rect frame(newFrame); 398 399 const int w = mDisplayWidth; 400 const int h = mDisplayHeight; 401 402 Transform R; 403 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 404 405 if (!frame.isValid()) { 406 // the destination frame can be invalid if it has never been set, 407 // in that case we assume the whole display frame. 408 frame = Rect(w, h); 409 } 410 411 if (viewport.isEmpty()) { 412 // viewport can be invalid if it has never been set, in that case 413 // we assume the whole display size. 414 // it's also invalid to have an empty viewport, so we handle that 415 // case in the same way. 416 viewport = Rect(w, h); 417 if (R.getOrientation() & Transform::ROT_90) { 418 // viewport is always specified in the logical orientation 419 // of the display (ie: post-rotation). 420 swap(viewport.right, viewport.bottom); 421 } 422 } 423 424 dirtyRegion.set(getBounds()); 425 426 Transform TL, TP, S; 427 float src_width = viewport.width(); 428 float src_height = viewport.height(); 429 float dst_width = frame.width(); 430 float dst_height = frame.height(); 431 if (src_width != dst_width || src_height != dst_height) { 432 float sx = dst_width / src_width; 433 float sy = dst_height / src_height; 434 S.set(sx, 0, 0, sy); 435 } 436 437 float src_x = viewport.left; 438 float src_y = viewport.top; 439 float dst_x = frame.left; 440 float dst_y = frame.top; 441 TL.set(-src_x, -src_y); 442 TP.set(dst_x, dst_y); 443 444 // The viewport and frame are both in the logical orientation. 445 // Apply the logical translation, scale to physical size, apply the 446 // physical translation and finally rotate to the physical orientation. 447 mGlobalTransform = R * TP * S * TL; 448 449 const uint8_t type = mGlobalTransform.getType(); 450 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 451 (type >= Transform::SCALE)); 452 453 mScissor = mGlobalTransform.transform(viewport); 454 if (mScissor.isEmpty()) { 455 mScissor = getBounds(); 456 } 457 458 mOrientation = orientation; 459 mViewport = viewport; 460 mFrame = frame; 461} 462 463void DisplayDevice::dump(String8& result) const { 464 const Transform& tr(mGlobalTransform); 465 result.appendFormat( 466 "+ DisplayDevice: %s\n" 467 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), " 468 "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%zu\n" 469 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 470 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 471 mDisplayName.string(), mType, mHwcDisplayId, 472 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(), 473 mOrientation, tr.getType(), getPageFlipCount(), 474 mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(), 475 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 476 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, 477 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom, 478 tr[0][0], tr[1][0], tr[2][0], 479 tr[0][1], tr[1][1], tr[2][1], 480 tr[0][2], tr[1][2], tr[2][2]); 481 482 String8 surfaceDump; 483 mDisplaySurface->dump(surfaceDump); 484 result.append(surfaceDump); 485} 486