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