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