DisplayDevice.cpp revision eabe3140f11e515639e7a70a1286dd6af7352c9e
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 const sp<LayerBase>& layer(layers[i]); 291 if (layer->isSecure()) { 292 mSecureLayerVisible = true; 293 } 294 } 295} 296 297const Vector< sp<LayerBase> >& DisplayDevice::getVisibleLayersSortedByZ() const { 298 return mVisibleLayersSortedByZ; 299} 300 301bool DisplayDevice::getSecureLayerVisible() const { 302 return mSecureLayerVisible; 303} 304 305Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 306 Region dirty; 307 if (repaintEverything) { 308 dirty.set(getBounds()); 309 } else { 310 const Transform& planeTransform(mGlobalTransform); 311 dirty = planeTransform.transform(this->dirtyRegion); 312 dirty.andSelf(getBounds()); 313 } 314 return dirty; 315} 316 317// ---------------------------------------------------------------------------- 318 319bool DisplayDevice::canDraw() const { 320 return mScreenAcquired; 321} 322 323void DisplayDevice::releaseScreen() const { 324 mScreenAcquired = false; 325} 326 327void DisplayDevice::acquireScreen() const { 328 mScreenAcquired = true; 329} 330 331bool DisplayDevice::isScreenAcquired() const { 332 return mScreenAcquired; 333} 334 335// ---------------------------------------------------------------------------- 336 337void DisplayDevice::setLayerStack(uint32_t stack) { 338 mLayerStack = stack; 339 dirtyRegion.set(bounds()); 340} 341 342// ---------------------------------------------------------------------------- 343 344status_t DisplayDevice::orientationToTransfrom( 345 int orientation, int w, int h, Transform* tr) 346{ 347 uint32_t flags = 0; 348 switch (orientation) { 349 case DisplayState::eOrientationDefault: 350 flags = Transform::ROT_0; 351 break; 352 case DisplayState::eOrientation90: 353 flags = Transform::ROT_90; 354 break; 355 case DisplayState::eOrientation180: 356 flags = Transform::ROT_180; 357 break; 358 case DisplayState::eOrientation270: 359 flags = Transform::ROT_270; 360 break; 361 default: 362 return BAD_VALUE; 363 } 364 tr->set(flags, w, h); 365 return NO_ERROR; 366} 367 368void DisplayDevice::setProjection(int orientation, 369 const Rect& newViewport, const Rect& newFrame) { 370 Rect viewport(newViewport); 371 Rect frame(newFrame); 372 373 const int w = mDisplayWidth; 374 const int h = mDisplayHeight; 375 376 Transform R; 377 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 378 379 if (!frame.isValid()) { 380 // the destination frame can be invalid if it has never been set, 381 // in that case we assume the whole display frame. 382 frame = Rect(w, h); 383 } 384 385 if (viewport.isEmpty()) { 386 // viewport can be invalid if it has never been set, in that case 387 // we assume the whole display size. 388 // it's also invalid to have an empty viewport, so we handle that 389 // case in the same way. 390 viewport = Rect(w, h); 391 if (R.getOrientation() & Transform::ROT_90) { 392 // viewport is always specified in the logical orientation 393 // of the display (ie: post-rotation). 394 swap(viewport.right, viewport.bottom); 395 } 396 } 397 398 dirtyRegion.set(getBounds()); 399 400 Transform TL, TP, S; 401 float src_width = viewport.width(); 402 float src_height = viewport.height(); 403 float dst_width = frame.width(); 404 float dst_height = frame.height(); 405 if (src_width != dst_width || src_height != dst_height) { 406 float sx = dst_width / src_width; 407 float sy = dst_height / src_height; 408 S.set(sx, 0, 0, sy); 409 } 410 411 float src_x = viewport.left; 412 float src_y = viewport.top; 413 float dst_x = frame.left; 414 float dst_y = frame.top; 415 TL.set(-src_x, -src_y); 416 TP.set(dst_x, dst_y); 417 418 // The viewport and frame are both in the logical orientation. 419 // Apply the logical translation, scale to physical size, apply the 420 // physical translation and finally rotate to the physical orientation. 421 mGlobalTransform = R * TP * S * TL; 422 423 const uint8_t type = mGlobalTransform.getType(); 424 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 425 (type >= Transform::SCALE)); 426 427 mScissor = mGlobalTransform.transform(viewport); 428 if (mScissor.isEmpty()) { 429 mScissor.set(getBounds()); 430 } 431 432 mOrientation = orientation; 433 mViewport = viewport; 434 mFrame = frame; 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