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