DisplayDevice.cpp revision d8552d796cbcb9a89711fc8f97b34838da5cbdb7
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 <GLES/gl.h> 31#include <EGL/egl.h> 32#include <EGL/eglext.h> 33 34#include <hardware/gralloc.h> 35 36#include "DisplayHardware/FramebufferSurface.h" 37#include "DisplayHardware/HWComposer.h" 38 39#include "DisplayDevice.h" 40#include "GLExtensions.h" 41#include "SurfaceFlinger.h" 42#include "LayerBase.h" 43 44// ---------------------------------------------------------------------------- 45using namespace android; 46// ---------------------------------------------------------------------------- 47 48static __attribute__((noinline)) 49void checkGLErrors() 50{ 51 do { 52 // there could be more than one error flag 53 GLenum error = glGetError(); 54 if (error == GL_NO_ERROR) 55 break; 56 ALOGE("GL error 0x%04x", int(error)); 57 } while(true); 58} 59 60static __attribute__((noinline)) 61void checkEGLErrors(const char* token) 62{ 63 struct EGLUtils { 64 static const char *strerror(EGLint err) { 65 switch (err){ 66 case EGL_SUCCESS: return "EGL_SUCCESS"; 67 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; 68 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; 69 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; 70 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; 71 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; 72 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; 73 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; 74 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; 75 case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; 76 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; 77 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; 78 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; 79 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; 80 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; 81 default: return "UNKNOWN"; 82 } 83 } 84 }; 85 86 EGLint error = eglGetError(); 87 if (error && error != EGL_SUCCESS) { 88 ALOGE("%s: EGL error 0x%04x (%s)", 89 token, int(error), EGLUtils::strerror(error)); 90 } 91} 92 93// ---------------------------------------------------------------------------- 94 95/* 96 * Initialize the display to the specified values. 97 * 98 */ 99 100DisplayDevice::DisplayDevice() 101 : mId(0), 102 mDisplay(EGL_NO_DISPLAY), 103 mSurface(EGL_NO_SURFACE), 104 mContext(EGL_NO_CONTEXT) 105{ 106} 107 108DisplayDevice::DisplayDevice( 109 const sp<SurfaceFlinger>& flinger, 110 int display, 111 const sp<ANativeWindow>& surface, 112 EGLConfig config) 113 : mFlinger(flinger), 114 mId(display), 115 mNativeWindow(surface), 116 mDisplay(EGL_NO_DISPLAY), 117 mSurface(EGL_NO_SURFACE), 118 mContext(EGL_NO_CONTEXT), 119 mDpiX(), mDpiY(), 120 mDensity(), 121 mDisplayWidth(), mDisplayHeight(), mFormat(), 122 mFlags(), 123 mPageFlipCount(), 124 mSecureLayerVisible(false), 125 mScreenAcquired(false), 126 mOrientation(), 127 mLayerStack(0) 128{ 129 init(config); 130} 131 132DisplayDevice::~DisplayDevice() { 133 // DO NOT call terminate() from here, because we create 134 // temporaries of this class (on the stack typically), and we don't 135 // want to destroy the EGLSurface in that case 136} 137 138void DisplayDevice::terminate() { 139 if (mSurface != EGL_NO_SURFACE) { 140 eglDestroySurface(mDisplay, mSurface); 141 mSurface = EGL_NO_SURFACE; 142 } 143} 144 145bool DisplayDevice::isValid() const { 146 return mFlinger != NULL; 147} 148 149float DisplayDevice::getDpiX() const { 150 return mDpiX; 151} 152 153float DisplayDevice::getDpiY() const { 154 return mDpiY; 155} 156 157float DisplayDevice::getDensity() const { 158 return mDensity; 159} 160 161int DisplayDevice::getWidth() const { 162 return mDisplayWidth; 163} 164 165int DisplayDevice::getHeight() const { 166 return mDisplayHeight; 167} 168 169PixelFormat DisplayDevice::getFormat() const { 170 return mFormat; 171} 172 173EGLSurface DisplayDevice::getEGLSurface() const { 174 return mSurface; 175} 176 177void DisplayDevice::init(EGLConfig config) 178{ 179 ANativeWindow* const window = mNativeWindow.get(); 180 181 int concreteType; 182 window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &concreteType); 183 if (concreteType == NATIVE_WINDOW_FRAMEBUFFER) { 184 mFramebufferSurface = static_cast<FramebufferSurface *>(mNativeWindow.get()); 185 } 186 187 int format; 188 window->query(window, NATIVE_WINDOW_FORMAT, &format); 189 mDpiX = window->xdpi; 190 mDpiY = window->ydpi; 191 192 // TODO: Not sure if display density should handled by SF any longer 193 class Density { 194 static int getDensityFromProperty(char const* propName) { 195 char property[PROPERTY_VALUE_MAX]; 196 int density = 0; 197 if (property_get(propName, property, NULL) > 0) { 198 density = atoi(property); 199 } 200 return density; 201 } 202 public: 203 static int getEmuDensity() { 204 return getDensityFromProperty("qemu.sf.lcd_density"); } 205 static int getBuildDensity() { 206 return getDensityFromProperty("ro.sf.lcd_density"); } 207 }; 208 // The density of the device is provided by a build property 209 mDensity = Density::getBuildDensity() / 160.0f; 210 if (mDensity == 0) { 211 // the build doesn't provide a density -- this is wrong! 212 // use xdpi instead 213 ALOGE("ro.sf.lcd_density must be defined as a build property"); 214 mDensity = mDpiX / 160.0f; 215 } 216 if (Density::getEmuDensity()) { 217 // if "qemu.sf.lcd_density" is specified, it overrides everything 218 mDpiX = mDpiY = mDensity = Density::getEmuDensity(); 219 mDensity /= 160.0f; 220 } 221 222 /* 223 * Create our display's surface 224 */ 225 226 EGLSurface surface; 227 EGLint w, h; 228 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 229 surface = eglCreateWindowSurface(display, config, window, NULL); 230 eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth); 231 eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight); 232 233 if (mFramebufferSurface != NULL) { 234 if (mFramebufferSurface->isUpdateOnDemand()) { 235 mFlags |= PARTIAL_UPDATES; 236 // if we have partial updates, we definitely don't need to 237 // preserve the backbuffer, which may be costly. 238 eglSurfaceAttrib(display, surface, 239 EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); 240 } 241 } 242 243 mDisplay = display; 244 mSurface = surface; 245 mFormat = format; 246 mPageFlipCount = 0; 247 248 // initialize the display orientation transform. 249 DisplayDevice::setOrientation(ISurfaceComposer::eOrientationDefault); 250} 251 252uint32_t DisplayDevice::getPageFlipCount() const { 253 return mPageFlipCount; 254} 255 256status_t DisplayDevice::compositionComplete() const { 257 if (mFramebufferSurface == NULL) { 258 return NO_ERROR; 259 } 260 return mFramebufferSurface->compositionComplete(); 261} 262 263void DisplayDevice::flip(const Region& dirty) const 264{ 265 checkGLErrors(); 266 267 EGLDisplay dpy = mDisplay; 268 EGLSurface surface = mSurface; 269 270#ifdef EGL_ANDROID_swap_rectangle 271 if (mFlags & SWAP_RECTANGLE) { 272 const Region newDirty(dirty.intersect(bounds())); 273 const Rect b(newDirty.getBounds()); 274 eglSetSwapRectangleANDROID(dpy, surface, 275 b.left, b.top, b.width(), b.height()); 276 } 277#endif 278 279 if (mFlags & PARTIAL_UPDATES) { 280 if (mFramebufferSurface != NULL) { 281 mFramebufferSurface->setUpdateRectangle(dirty.getBounds()); 282 } 283 } 284 285 mPageFlipCount++; 286} 287 288uint32_t DisplayDevice::getFlags() const 289{ 290 return mFlags; 291} 292 293void DisplayDevice::dump(String8& res) const 294{ 295 if (mFramebufferSurface != NULL) { 296 mFramebufferSurface->dump(res); 297 } 298} 299 300void DisplayDevice::makeCurrent(const DisplayDevice& hw, EGLContext ctx) { 301 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 302 if (sur != hw.mSurface) { 303 EGLDisplay dpy = eglGetCurrentDisplay(); 304 eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx); 305 } 306} 307 308// ---------------------------------------------------------------------------- 309 310void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { 311 mVisibleLayersSortedByZ = layers; 312 size_t count = layers.size(); 313 for (size_t i=0 ; i<count ; i++) { 314 if (layers[i]->isSecure()) { 315 mSecureLayerVisible = true; 316 } 317 } 318} 319 320Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const { 321 return mVisibleLayersSortedByZ; 322} 323 324bool DisplayDevice::getSecureLayerVisible() const { 325 return mSecureLayerVisible; 326} 327 328// ---------------------------------------------------------------------------- 329 330bool DisplayDevice::canDraw() const { 331 return mScreenAcquired; 332} 333 334void DisplayDevice::releaseScreen() const { 335 mScreenAcquired = false; 336} 337 338void DisplayDevice::acquireScreen() const { 339 mScreenAcquired = true; 340} 341 342bool DisplayDevice::isScreenAcquired() const { 343 return mScreenAcquired; 344} 345 346// ---------------------------------------------------------------------------- 347 348status_t DisplayDevice::orientationToTransfrom( 349 int orientation, int w, int h, Transform* tr) 350{ 351 uint32_t flags = 0; 352 switch (orientation) { 353 case ISurfaceComposer::eOrientationDefault: 354 flags = Transform::ROT_0; 355 break; 356 case ISurfaceComposer::eOrientation90: 357 flags = Transform::ROT_90; 358 break; 359 case ISurfaceComposer::eOrientation180: 360 flags = Transform::ROT_180; 361 break; 362 case ISurfaceComposer::eOrientation270: 363 flags = Transform::ROT_270; 364 break; 365 default: 366 return BAD_VALUE; 367 } 368 tr->set(flags, w, h); 369 return NO_ERROR; 370} 371 372status_t DisplayDevice::setOrientation(int orientation) { 373 int w = mDisplayWidth; 374 int h = mDisplayHeight; 375 376 DisplayDevice::orientationToTransfrom( 377 orientation, w, h, &mGlobalTransform); 378 if (orientation & ISurfaceComposer::eOrientationSwapMask) { 379 int tmp = w; 380 w = h; 381 h = tmp; 382 } 383 mOrientation = orientation; 384 dirtyRegion.set(bounds()); 385 return NO_ERROR; 386} 387