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