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