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