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