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