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