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