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