DisplayDevice.cpp revision 766dc49c17dda977bf7b93a5fd8da41c0b737611
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/SurfaceTextureClient.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 mNativeWindow(nativeWindow), 81 mFramebufferSurface(framebufferSurface), 82 mDisplay(EGL_NO_DISPLAY), 83 mSurface(EGL_NO_SURFACE), 84 mContext(EGL_NO_CONTEXT), 85 mDisplayWidth(), mDisplayHeight(), mFormat(), 86 mFlags(), 87 mPageFlipCount(), 88 mIsSecure(isSecure), 89 mSecureLayerVisible(false), 90 mScreenAcquired(false), 91 mLayerStack(0), 92 mOrientation() 93{ 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 if (mFramebufferSurface == NULL) { 186 return NO_ERROR; 187 } 188 return mFramebufferSurface->compositionComplete(); 189} 190 191void DisplayDevice::flip(const Region& dirty) const 192{ 193 checkGLErrors(); 194 195 EGLDisplay dpy = mDisplay; 196 EGLSurface surface = mSurface; 197 198#ifdef EGL_ANDROID_swap_rectangle 199 if (mFlags & SWAP_RECTANGLE) { 200 const Region newDirty(dirty.intersect(bounds())); 201 const Rect b(newDirty.getBounds()); 202 eglSetSwapRectangleANDROID(dpy, surface, 203 b.left, b.top, b.width(), b.height()); 204 } 205#endif 206 207 mPageFlipCount++; 208} 209 210void DisplayDevice::swapBuffers(HWComposer& hwc) const { 211 EGLBoolean success = EGL_TRUE; 212 if (hwc.initCheck() != NO_ERROR) { 213 // no HWC, we call eglSwapBuffers() 214 success = eglSwapBuffers(mDisplay, mSurface); 215 } else { 216 // We have a valid HWC, but not all displays can use it, in particular 217 // the virtual displays are on their own. 218 // TODO: HWC 1.2 will allow virtual displays 219 if (mType >= DisplayDevice::DISPLAY_VIRTUAL) { 220 // always call eglSwapBuffers() for virtual displays 221 success = eglSwapBuffers(mDisplay, mSurface); 222 } else if (hwc.supportsFramebufferTarget()) { 223 // as of hwc 1.1 we always call eglSwapBuffers if we have some 224 // GLES layers 225 if (hwc.hasGlesComposition(mType)) { 226 success = eglSwapBuffers(mDisplay, mSurface); 227 } 228 } else { 229 // HWC doesn't have the framebuffer target, we don't call 230 // eglSwapBuffers(), since this is handled by HWComposer::commit(). 231 } 232 } 233 234 if (!success) { 235 EGLint error = eglGetError(); 236 if (error == EGL_CONTEXT_LOST || 237 mType == DisplayDevice::DISPLAY_PRIMARY) { 238 LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x", 239 mDisplay, mSurface, error); 240 } 241 } 242} 243 244void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const { 245 if (hwc.initCheck() == NO_ERROR) { 246 if (hwc.supportsFramebufferTarget()) { 247 int fd = hwc.getAndResetReleaseFenceFd(mType); 248 mFramebufferSurface->setReleaseFenceFd(fd); 249 } 250 } 251} 252 253uint32_t DisplayDevice::getFlags() const 254{ 255 return mFlags; 256} 257 258EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, 259 const sp<const DisplayDevice>& hw, EGLContext ctx) { 260 EGLBoolean result = EGL_TRUE; 261 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 262 if (sur != hw->mSurface) { 263 result = eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx); 264 if (result == EGL_TRUE) { 265 setViewportAndProjection(hw); 266 } 267 } 268 return result; 269} 270 271void DisplayDevice::setViewportAndProjection(const sp<const DisplayDevice>& hw) { 272 GLsizei w = hw->mDisplayWidth; 273 GLsizei h = hw->mDisplayHeight; 274 glViewport(0, 0, w, h); 275 glMatrixMode(GL_PROJECTION); 276 glLoadIdentity(); 277 // put the origin in the left-bottom corner 278 glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h 279 glMatrixMode(GL_MODELVIEW); 280} 281 282// ---------------------------------------------------------------------------- 283 284void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { 285 mVisibleLayersSortedByZ = layers; 286 mSecureLayerVisible = false; 287 size_t count = layers.size(); 288 for (size_t i=0 ; i<count ; i++) { 289 if (layers[i]->isSecure()) { 290 mSecureLayerVisible = true; 291 } 292 } 293} 294 295const Vector< sp<LayerBase> >& DisplayDevice::getVisibleLayersSortedByZ() const { 296 return mVisibleLayersSortedByZ; 297} 298 299bool DisplayDevice::getSecureLayerVisible() const { 300 return mSecureLayerVisible; 301} 302 303Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 304 Region dirty; 305 if (repaintEverything) { 306 dirty.set(getBounds()); 307 } else { 308 const Transform& planeTransform(mGlobalTransform); 309 dirty = planeTransform.transform(this->dirtyRegion); 310 dirty.andSelf(getBounds()); 311 } 312 return dirty; 313} 314 315// ---------------------------------------------------------------------------- 316 317bool DisplayDevice::canDraw() const { 318 return mScreenAcquired; 319} 320 321void DisplayDevice::releaseScreen() const { 322 mScreenAcquired = false; 323} 324 325void DisplayDevice::acquireScreen() const { 326 mScreenAcquired = true; 327} 328 329bool DisplayDevice::isScreenAcquired() const { 330 return mScreenAcquired; 331} 332 333// ---------------------------------------------------------------------------- 334 335void DisplayDevice::setLayerStack(uint32_t stack) { 336 mLayerStack = stack; 337 dirtyRegion.set(bounds()); 338} 339 340// ---------------------------------------------------------------------------- 341 342status_t DisplayDevice::orientationToTransfrom( 343 int orientation, int w, int h, Transform* tr) 344{ 345 uint32_t flags = 0; 346 switch (orientation) { 347 case DisplayState::eOrientationDefault: 348 flags = Transform::ROT_0; 349 break; 350 case DisplayState::eOrientation90: 351 flags = Transform::ROT_90; 352 break; 353 case DisplayState::eOrientation180: 354 flags = Transform::ROT_180; 355 break; 356 case DisplayState::eOrientation270: 357 flags = Transform::ROT_270; 358 break; 359 default: 360 return BAD_VALUE; 361 } 362 tr->set(flags, w, h); 363 return NO_ERROR; 364} 365 366void DisplayDevice::setProjection(int orientation, 367 const Rect& viewport, const Rect& frame) { 368 mOrientation = orientation; 369 mViewport = viewport; 370 mFrame = frame; 371 updateGeometryTransform(); 372} 373 374void DisplayDevice::updateGeometryTransform() { 375 int w = mDisplayWidth; 376 int h = mDisplayHeight; 377 Transform TL, TP, R, S; 378 if (DisplayDevice::orientationToTransfrom( 379 mOrientation, w, h, &R) == NO_ERROR) { 380 dirtyRegion.set(bounds()); 381 382 Rect viewport(mViewport); 383 Rect frame(mFrame); 384 385 if (!frame.isValid()) { 386 // the destination frame can be invalid if it has never been set, 387 // in that case we assume the whole display frame. 388 frame = Rect(w, h); 389 } 390 391 if (viewport.isEmpty()) { 392 // viewport can be invalid if it has never been set, in that case 393 // we assume the whole display size. 394 // it's also invalid to have an empty viewport, so we handle that 395 // case in the same way. 396 viewport = Rect(w, h); 397 if (R.getOrientation() & Transform::ROT_90) { 398 // viewport is always specified in the logical orientation 399 // of the display (ie: post-rotation). 400 swap(viewport.right, viewport.bottom); 401 } 402 } 403 404 float src_width = viewport.width(); 405 float src_height = viewport.height(); 406 float dst_width = frame.width(); 407 float dst_height = frame.height(); 408 if (src_width != dst_width || src_height != dst_height) { 409 float sx = dst_width / src_width; 410 float sy = dst_height / src_height; 411 S.set(sx, 0, 0, sy); 412 } 413 414 float src_x = viewport.left; 415 float src_y = viewport.top; 416 float dst_x = frame.left; 417 float dst_y = frame.top; 418 TL.set(-src_x, -src_y); 419 TP.set(dst_x, dst_y); 420 421 // The viewport and frame are both in the logical orientation. 422 // Apply the logical translation, scale to physical size, apply the 423 // physical translation and finally rotate to the physical orientation. 424 mGlobalTransform = R * TP * S * TL; 425 426 const uint8_t type = mGlobalTransform.getType(); 427 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 428 (type >= Transform::SCALE)); 429 430 mScissor = mGlobalTransform.transform(mViewport); 431 if (mScissor.isEmpty()) { 432 mScissor.set(getBounds()); 433 } 434 } 435} 436 437void DisplayDevice::dump(String8& result, char* buffer, size_t SIZE) const { 438 const Transform& tr(mGlobalTransform); 439 snprintf(buffer, SIZE, 440 "+ DisplayDevice: %s\n" 441 " type=%x, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), " 442 "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n" 443 " v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 444 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 445 mDisplayName.string(), mType, 446 mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(), 447 mOrientation, tr.getType(), getPageFlipCount(), 448 mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(), 449 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 450 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, 451 mScissor.left, mScissor.top, mScissor.right, mScissor.bottom, 452 tr[0][0], tr[1][0], tr[2][0], 453 tr[0][1], tr[1][1], tr[2][1], 454 tr[0][2], tr[1][2], tr[2][2]); 455 456 result.append(buffer); 457 458 String8 fbtargetDump; 459 if (mFramebufferSurface != NULL) { 460 mFramebufferSurface->dump(fbtargetDump); 461 result.append(fbtargetDump); 462 } 463} 464