DisplayDevice.cpp revision 86efcc0cbc1d94250b72ef1f2ea8700a04cd2781
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#endif 198 199 mPageFlipCount++; 200} 201 202status_t DisplayDevice::beginFrame() const { 203 return mDisplaySurface->beginFrame(); 204} 205 206status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const { 207 DisplaySurface::CompositionType compositionType; 208 bool haveGles = hwc.hasGlesComposition(mHwcDisplayId); 209 bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId); 210 if (haveGles && haveHwc) { 211 compositionType = DisplaySurface::COMPOSITION_MIXED; 212 } else if (haveGles) { 213 compositionType = DisplaySurface::COMPOSITION_GLES; 214 } else if (haveHwc) { 215 compositionType = DisplaySurface::COMPOSITION_HWC; 216 } else { 217 // Nothing to do -- when turning the screen off we get a frame like 218 // this. Call it a HWC frame since we won't be doing any GLES work but 219 // will do a prepare/set cycle. 220 compositionType = DisplaySurface::COMPOSITION_HWC; 221 } 222 return mDisplaySurface->prepareFrame(compositionType); 223} 224 225void DisplayDevice::swapBuffers(HWComposer& hwc) const { 226 // We need to call eglSwapBuffers() if: 227 // (1) we don't have a hardware composer, or 228 // (2) we did GLES composition this frame, and either 229 // (a) we have framebuffer target support (not present on legacy 230 // devices, where HWComposer::commit() handles things); or 231 // (b) this is a virtual display 232 if (hwc.initCheck() != NO_ERROR || 233 (hwc.hasGlesComposition(mHwcDisplayId) && 234 (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) { 235 EGLBoolean success = eglSwapBuffers(mDisplay, mSurface); 236 if (!success) { 237 EGLint error = eglGetError(); 238 if (error == EGL_CONTEXT_LOST || 239 mType == DisplayDevice::DISPLAY_PRIMARY) { 240 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x", 241 mDisplay, mSurface, error); 242 } else { 243 ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x", 244 mDisplay, mSurface, error); 245 } 246 } 247 } 248 249 status_t result = mDisplaySurface->advanceFrame(); 250 if (result != NO_ERROR) { 251 ALOGE("[%s] failed pushing new frame to HWC: %d", 252 mDisplayName.string(), result); 253 } 254} 255 256void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const { 257 if (hwc.initCheck() == NO_ERROR) { 258 mDisplaySurface->onFrameCommitted(); 259 } 260} 261 262uint32_t DisplayDevice::getFlags() const 263{ 264 return mFlags; 265} 266 267EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const { 268 EGLBoolean result = EGL_TRUE; 269 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 270 if (sur != mSurface) { 271 result = eglMakeCurrent(dpy, mSurface, mSurface, ctx); 272 if (result == EGL_TRUE) { 273 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) 274 eglSwapInterval(dpy, 0); 275 } 276 } 277 setViewportAndProjection(); 278 return result; 279} 280 281void DisplayDevice::setViewportAndProjection() const { 282 size_t w = mDisplayWidth; 283 size_t h = mDisplayHeight; 284 mFlinger->getRenderEngine().setViewportAndProjection(w, h, w, h, false); 285} 286 287// ---------------------------------------------------------------------------- 288 289void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { 290 mVisibleLayersSortedByZ = layers; 291 mSecureLayerVisible = false; 292 size_t count = layers.size(); 293 for (size_t i=0 ; i<count ; i++) { 294 const sp<Layer>& layer(layers[i]); 295 if (layer->isSecure()) { 296 mSecureLayerVisible = true; 297 } 298 } 299} 300 301const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { 302 return mVisibleLayersSortedByZ; 303} 304 305bool DisplayDevice::getSecureLayerVisible() const { 306 return mSecureLayerVisible; 307} 308 309Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 310 Region dirty; 311 if (repaintEverything) { 312 dirty.set(getBounds()); 313 } else { 314 const Transform& planeTransform(mGlobalTransform); 315 dirty = planeTransform.transform(this->dirtyRegion); 316 dirty.andSelf(getBounds()); 317 } 318 return dirty; 319} 320 321// ---------------------------------------------------------------------------- 322 323bool DisplayDevice::canDraw() const { 324 return mScreenAcquired; 325} 326 327void DisplayDevice::releaseScreen() const { 328 mScreenAcquired = false; 329} 330 331void DisplayDevice::acquireScreen() const { 332 mScreenAcquired = true; 333} 334 335bool DisplayDevice::isScreenAcquired() const { 336 return mScreenAcquired; 337} 338 339// ---------------------------------------------------------------------------- 340 341void DisplayDevice::setLayerStack(uint32_t stack) { 342 mLayerStack = stack; 343 dirtyRegion.set(bounds()); 344} 345 346// ---------------------------------------------------------------------------- 347 348uint32_t DisplayDevice::getOrientationTransform() const { 349 uint32_t transform = 0; 350 switch (mOrientation) { 351 case DisplayState::eOrientationDefault: 352 transform = Transform::ROT_0; 353 break; 354 case DisplayState::eOrientation90: 355 transform = Transform::ROT_90; 356 break; 357 case DisplayState::eOrientation180: 358 transform = Transform::ROT_180; 359 break; 360 case DisplayState::eOrientation270: 361 transform = Transform::ROT_270; 362 break; 363 } 364 return transform; 365} 366 367status_t DisplayDevice::orientationToTransfrom( 368 int orientation, int w, int h, Transform* tr) 369{ 370 uint32_t flags = 0; 371 switch (orientation) { 372 case DisplayState::eOrientationDefault: 373 flags = Transform::ROT_0; 374 break; 375 case DisplayState::eOrientation90: 376 flags = Transform::ROT_90; 377 break; 378 case DisplayState::eOrientation180: 379 flags = Transform::ROT_180; 380 break; 381 case DisplayState::eOrientation270: 382 flags = Transform::ROT_270; 383 break; 384 default: 385 return BAD_VALUE; 386 } 387 tr->set(flags, w, h); 388 return NO_ERROR; 389} 390 391void DisplayDevice::setProjection(int orientation, 392 const Rect& newViewport, const Rect& newFrame) { 393 Rect viewport(newViewport); 394 Rect frame(newFrame); 395 396 const int w = mDisplayWidth; 397 const int h = mDisplayHeight; 398 399 Transform R; 400 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 401 402 if (!frame.isValid()) { 403 // the destination frame can be invalid if it has never been set, 404 // in that case we assume the whole display frame. 405 frame = Rect(w, h); 406 } 407 408 if (viewport.isEmpty()) { 409 // viewport can be invalid if it has never been set, in that case 410 // we assume the whole display size. 411 // it's also invalid to have an empty viewport, so we handle that 412 // case in the same way. 413 viewport = Rect(w, h); 414 if (R.getOrientation() & Transform::ROT_90) { 415 // viewport is always specified in the logical orientation 416 // of the display (ie: post-rotation). 417 swap(viewport.right, viewport.bottom); 418 } 419 } 420 421 dirtyRegion.set(getBounds()); 422 423 Transform TL, TP, S; 424 float src_width = viewport.width(); 425 float src_height = viewport.height(); 426 float dst_width = frame.width(); 427 float dst_height = frame.height(); 428 if (src_width != dst_width || src_height != dst_height) { 429 float sx = dst_width / src_width; 430 float sy = dst_height / src_height; 431 S.set(sx, 0, 0, sy); 432 } 433 434 float src_x = viewport.left; 435 float src_y = viewport.top; 436 float dst_x = frame.left; 437 float dst_y = frame.top; 438 TL.set(-src_x, -src_y); 439 TP.set(dst_x, dst_y); 440 441 // The viewport and frame are both in the logical orientation. 442 // Apply the logical translation, scale to physical size, apply the 443 // physical translation and finally rotate to the physical orientation. 444 mGlobalTransform = R * TP * S * TL; 445 446 const uint8_t type = mGlobalTransform.getType(); 447 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 448 (type >= Transform::SCALE)); 449 450 mScissor = mGlobalTransform.transform(viewport); 451 if (mScissor.isEmpty()) { 452 mScissor = getBounds(); 453 } 454 455 mOrientation = orientation; 456 mViewport = viewport; 457 mFrame = frame; 458} 459 460void DisplayDevice::dump(String8& result) const { 461 const Transform& tr(mGlobalTransform); 462 result.appendFormat( 463 "+ DisplayDevice: %s\n" 464 " type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), " 465 "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%zu\n" 466 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 467 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 468 mDisplayName.string(), mType, mHwcDisplayId, 469 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(), 470 mOrientation, tr.getType(), getPageFlipCount(), 471 mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(), 472 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 473 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, 474 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom, 475 tr[0][0], tr[1][0], tr[2][0], 476 tr[0][1], tr[1][1], tr[2][1], 477 tr[0][2], tr[1][2], tr[2][2]); 478 479 String8 surfaceDump; 480 mDisplaySurface->dump(surfaceDump); 481 result.append(surfaceDump); 482} 483