DisplayDevice.cpp revision d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3
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 const sp<SurfaceFlinger>& flinger, 102 int display, 103 const sp<SurfaceTextureClient>& surface, 104 EGLConfig config) 105 : mFlinger(flinger), 106 mDisplayId(display), 107 mNativeWindow(surface), 108 mDisplay(EGL_NO_DISPLAY), 109 mSurface(EGL_NO_SURFACE), 110 mContext(EGL_NO_CONTEXT), 111 mDpiX(), mDpiY(), 112 mRefreshRate(), 113 mDensity(), 114 mDisplayWidth(), mDisplayHeight(), mFormat(), 115 mFlags(), 116 mPageFlipCount(), 117 mRefreshPeriod(), 118 mSecureLayerVisible(false), 119 mScreenAcquired(false), 120 mOrientation(), 121 mLayerStack(0) 122{ 123 init(config); 124} 125 126DisplayDevice::~DisplayDevice() { 127} 128 129float DisplayDevice::getDpiX() const { 130 return mDpiX; 131} 132 133float DisplayDevice::getDpiY() const { 134 return mDpiY; 135} 136 137float DisplayDevice::getDensity() const { 138 return mDensity; 139} 140 141float DisplayDevice::getRefreshRate() const { 142 return mRefreshRate; 143} 144 145int DisplayDevice::getWidth() const { 146 return mDisplayWidth; 147} 148 149int DisplayDevice::getHeight() const { 150 return mDisplayHeight; 151} 152 153PixelFormat DisplayDevice::getFormat() const { 154 return mFormat; 155} 156 157EGLSurface DisplayDevice::getEGLSurface() const { 158 return mSurface; 159} 160 161status_t DisplayDevice::getInfo(DisplayInfo* info) const { 162 info->w = getWidth(); 163 info->h = getHeight(); 164 info->xdpi = getDpiX(); 165 info->ydpi = getDpiY(); 166 info->fps = getRefreshRate(); 167 info->density = getDensity(); 168 info->orientation = getOrientation(); 169 // TODO: this needs to go away (currently needed only by webkit) 170 getPixelFormatInfo(getFormat(), &info->pixelFormatInfo); 171 return NO_ERROR; 172} 173 174void DisplayDevice::init(EGLConfig config) 175{ 176 ANativeWindow* const window = mNativeWindow.get(); 177 178 int concreteType; 179 window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &concreteType); 180 if (concreteType == NATIVE_WINDOW_FRAMEBUFFER) { 181 mFramebufferSurface = static_cast<FramebufferSurface *>(mNativeWindow.get()); 182 } 183 184 int format; 185 window->query(window, NATIVE_WINDOW_FORMAT, &format); 186 mDpiX = window->xdpi; 187 mDpiY = window->ydpi; 188 if (mFramebufferSurface != NULL) { 189 mRefreshRate = mFramebufferSurface->getRefreshRate(); 190 } else { 191 mRefreshRate = 60; 192 } 193 mRefreshPeriod = nsecs_t(1e9 / mRefreshRate); 194 195 196 // TODO: Not sure if display density should handled by SF any longer 197 class Density { 198 static int getDensityFromProperty(char const* propName) { 199 char property[PROPERTY_VALUE_MAX]; 200 int density = 0; 201 if (property_get(propName, property, NULL) > 0) { 202 density = atoi(property); 203 } 204 return density; 205 } 206 public: 207 static int getEmuDensity() { 208 return getDensityFromProperty("qemu.sf.lcd_density"); } 209 static int getBuildDensity() { 210 return getDensityFromProperty("ro.sf.lcd_density"); } 211 }; 212 // The density of the device is provided by a build property 213 mDensity = Density::getBuildDensity() / 160.0f; 214 if (mDensity == 0) { 215 // the build doesn't provide a density -- this is wrong! 216 // use xdpi instead 217 ALOGE("ro.sf.lcd_density must be defined as a build property"); 218 mDensity = mDpiX / 160.0f; 219 } 220 if (Density::getEmuDensity()) { 221 // if "qemu.sf.lcd_density" is specified, it overrides everything 222 mDpiX = mDpiY = mDensity = Density::getEmuDensity(); 223 mDensity /= 160.0f; 224 } 225 226 /* 227 * Create our display's surface 228 */ 229 230 EGLSurface surface; 231 EGLint w, h; 232 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 233 surface = eglCreateWindowSurface(display, config, window, NULL); 234 eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth); 235 eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight); 236 237 if (mFramebufferSurface != NULL) { 238 if (mFramebufferSurface->isUpdateOnDemand()) { 239 mFlags |= PARTIAL_UPDATES; 240 // if we have partial updates, we definitely don't need to 241 // preserve the backbuffer, which may be costly. 242 eglSurfaceAttrib(display, surface, 243 EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); 244 } 245 } 246 247 mDisplay = display; 248 mSurface = surface; 249 mFormat = format; 250 mPageFlipCount = 0; 251 252 // initialize the display orientation transform. 253 DisplayDevice::setOrientation(ISurfaceComposer::eOrientationDefault); 254} 255 256uint32_t DisplayDevice::getPageFlipCount() const { 257 return mPageFlipCount; 258} 259 260nsecs_t DisplayDevice::getRefreshPeriod() const { 261 return mRefreshPeriod; 262} 263 264status_t DisplayDevice::compositionComplete() const { 265 if (mFramebufferSurface == NULL) { 266 return NO_ERROR; 267 } 268 return mFramebufferSurface->compositionComplete(); 269} 270 271void DisplayDevice::flip(const Region& dirty) const 272{ 273 checkGLErrors(); 274 275 EGLDisplay dpy = mDisplay; 276 EGLSurface surface = mSurface; 277 278#ifdef EGL_ANDROID_swap_rectangle 279 if (mFlags & SWAP_RECTANGLE) { 280 const Region newDirty(dirty.intersect(bounds())); 281 const Rect b(newDirty.getBounds()); 282 eglSetSwapRectangleANDROID(dpy, surface, 283 b.left, b.top, b.width(), b.height()); 284 } 285#endif 286 287 if (mFlags & PARTIAL_UPDATES) { 288 if (mFramebufferSurface != NULL) { 289 mFramebufferSurface->setUpdateRectangle(dirty.getBounds()); 290 } 291 } 292 293 mPageFlipCount++; 294} 295 296uint32_t DisplayDevice::getFlags() const 297{ 298 return mFlags; 299} 300 301void DisplayDevice::dump(String8& res) const 302{ 303 if (mFramebufferSurface != NULL) { 304 mFramebufferSurface->dump(res); 305 } 306} 307 308void DisplayDevice::makeCurrent(const DisplayDevice& hw, EGLContext ctx) { 309 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 310 if (sur != hw.mSurface) { 311 EGLDisplay dpy = eglGetCurrentDisplay(); 312 eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx); 313 } 314} 315 316// ---------------------------------------------------------------------------- 317 318void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { 319 mVisibleLayersSortedByZ = layers; 320 size_t count = layers.size(); 321 for (size_t i=0 ; i<count ; i++) { 322 if (layers[i]->isSecure()) { 323 mSecureLayerVisible = true; 324 } 325 } 326} 327 328Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const { 329 return mVisibleLayersSortedByZ; 330} 331 332bool DisplayDevice::getSecureLayerVisible() const { 333 return mSecureLayerVisible; 334} 335 336// ---------------------------------------------------------------------------- 337 338bool DisplayDevice::canDraw() const { 339 return mScreenAcquired; 340} 341 342void DisplayDevice::releaseScreen() const { 343 mScreenAcquired = false; 344} 345 346void DisplayDevice::acquireScreen() const { 347 mScreenAcquired = true; 348} 349 350bool DisplayDevice::isScreenAcquired() const { 351 return mScreenAcquired; 352} 353 354// ---------------------------------------------------------------------------- 355 356status_t DisplayDevice::orientationToTransfrom( 357 int orientation, int w, int h, Transform* tr) 358{ 359 uint32_t flags = 0; 360 switch (orientation) { 361 case ISurfaceComposer::eOrientationDefault: 362 flags = Transform::ROT_0; 363 break; 364 case ISurfaceComposer::eOrientation90: 365 flags = Transform::ROT_90; 366 break; 367 case ISurfaceComposer::eOrientation180: 368 flags = Transform::ROT_180; 369 break; 370 case ISurfaceComposer::eOrientation270: 371 flags = Transform::ROT_270; 372 break; 373 default: 374 return BAD_VALUE; 375 } 376 tr->set(flags, w, h); 377 return NO_ERROR; 378} 379 380status_t DisplayDevice::setOrientation(int orientation) { 381 int w = mDisplayWidth; 382 int h = mDisplayHeight; 383 384 DisplayDevice::orientationToTransfrom( 385 orientation, w, h, &mGlobalTransform); 386 if (orientation & ISurfaceComposer::eOrientationSwapMask) { 387 int tmp = w; 388 w = h; 389 h = tmp; 390 } 391 mOrientation = orientation; 392 return NO_ERROR; 393} 394