DisplayDevice.cpp revision 3ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2a
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 DisplayType type, const wp<IBinder>& displayToken, 72 const sp<ANativeWindow>& nativeWindow, 73 const sp<FramebufferSurface>& framebufferSurface, 74 EGLConfig config) 75 : mFlinger(flinger), 76 mType(type), mHwcDisplayId(-1), 77 mNativeWindow(nativeWindow), 78 mFramebufferSurface(framebufferSurface), 79 mDisplay(EGL_NO_DISPLAY), 80 mSurface(EGL_NO_SURFACE), 81 mContext(EGL_NO_CONTEXT), 82 mDisplayWidth(), mDisplayHeight(), mFormat(), 83 mFlags(), 84 mPageFlipCount(), 85 mSecureLayerVisible(false), 86 mScreenAcquired(false), 87 mOrientation(), 88 mLayerStack(0) 89{ 90 init(config); 91} 92 93DisplayDevice::~DisplayDevice() { 94 if (mSurface != EGL_NO_SURFACE) { 95 eglDestroySurface(mDisplay, mSurface); 96 mSurface = EGL_NO_SURFACE; 97 } 98} 99 100bool DisplayDevice::isValid() const { 101 return mFlinger != NULL; 102} 103 104int DisplayDevice::getWidth() const { 105 return mDisplayWidth; 106} 107 108int DisplayDevice::getHeight() const { 109 return mDisplayHeight; 110} 111 112PixelFormat DisplayDevice::getFormat() const { 113 return mFormat; 114} 115 116EGLSurface DisplayDevice::getEGLSurface() const { 117 return mSurface; 118} 119 120void DisplayDevice::init(EGLConfig config) 121{ 122 ANativeWindow* const window = mNativeWindow.get(); 123 124 int format; 125 window->query(window, NATIVE_WINDOW_FORMAT, &format); 126 127 /* 128 * Create our display's surface 129 */ 130 131 EGLSurface surface; 132 EGLint w, h; 133 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 134 surface = eglCreateWindowSurface(display, config, window, NULL); 135 eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth); 136 eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight); 137 138 mDisplay = display; 139 mSurface = surface; 140 mFormat = format; 141 mPageFlipCount = 0; 142 143 // external displays are always considered enabled 144 mScreenAcquired = (mType >= DisplayDevice::NUM_DISPLAY_TYPES); 145 146 // get an h/w composer ID 147 mHwcDisplayId = mFlinger->allocateHwcDisplayId(mType); 148 149 // initialize the display orientation transform. 150 DisplayDevice::setOrientation(DisplayState::eOrientationDefault); 151} 152 153uint32_t DisplayDevice::getPageFlipCount() const { 154 return mPageFlipCount; 155} 156 157status_t DisplayDevice::compositionComplete() const { 158 if (mFramebufferSurface == NULL) { 159 return NO_ERROR; 160 } 161 return mFramebufferSurface->compositionComplete(); 162} 163 164void DisplayDevice::flip(const Region& dirty) const 165{ 166 checkGLErrors(); 167 168 EGLDisplay dpy = mDisplay; 169 EGLSurface surface = mSurface; 170 171#ifdef EGL_ANDROID_swap_rectangle 172 if (mFlags & SWAP_RECTANGLE) { 173 const Region newDirty(dirty.intersect(bounds())); 174 const Rect b(newDirty.getBounds()); 175 eglSetSwapRectangleANDROID(dpy, surface, 176 b.left, b.top, b.width(), b.height()); 177 } 178#endif 179 180 mPageFlipCount++; 181} 182 183uint32_t DisplayDevice::getFlags() const 184{ 185 return mFlags; 186} 187 188void DisplayDevice::dump(String8& res) const 189{ 190 if (mFramebufferSurface != NULL) { 191 mFramebufferSurface->dump(res); 192 } 193} 194 195void DisplayDevice::makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx) { 196 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 197 if (sur != hw->mSurface) { 198 EGLDisplay dpy = eglGetCurrentDisplay(); 199 eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx); 200 } 201} 202 203// ---------------------------------------------------------------------------- 204 205void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { 206 mVisibleLayersSortedByZ = layers; 207 mSecureLayerVisible = false; 208 size_t count = layers.size(); 209 for (size_t i=0 ; i<count ; i++) { 210 if (layers[i]->isSecure()) { 211 mSecureLayerVisible = true; 212 } 213 } 214} 215 216const Vector< sp<LayerBase> >& DisplayDevice::getVisibleLayersSortedByZ() const { 217 return mVisibleLayersSortedByZ; 218} 219 220bool DisplayDevice::getSecureLayerVisible() const { 221 return mSecureLayerVisible; 222} 223 224Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 225 Region dirty; 226 const Transform& planeTransform(mGlobalTransform); 227 if (repaintEverything) { 228 dirty.set(getBounds()); 229 } else { 230 dirty = planeTransform.transform(this->dirtyRegion); 231 dirty.andSelf(getBounds()); 232 } 233 return dirty; 234} 235 236// ---------------------------------------------------------------------------- 237 238bool DisplayDevice::canDraw() const { 239 return mScreenAcquired; 240} 241 242void DisplayDevice::releaseScreen() const { 243 mScreenAcquired = false; 244} 245 246void DisplayDevice::acquireScreen() const { 247 mScreenAcquired = true; 248} 249 250bool DisplayDevice::isScreenAcquired() const { 251 return mScreenAcquired; 252} 253 254// ---------------------------------------------------------------------------- 255 256void DisplayDevice::setLayerStack(uint32_t stack) { 257 mLayerStack = stack; 258 dirtyRegion.set(bounds()); 259} 260 261// ---------------------------------------------------------------------------- 262 263status_t DisplayDevice::orientationToTransfrom( 264 int orientation, int w, int h, Transform* tr) 265{ 266 uint32_t flags = 0; 267 switch (orientation) { 268 case DisplayState::eOrientationDefault: 269 flags = Transform::ROT_0; 270 break; 271 case DisplayState::eOrientation90: 272 flags = Transform::ROT_90; 273 break; 274 case DisplayState::eOrientation180: 275 flags = Transform::ROT_180; 276 break; 277 case DisplayState::eOrientation270: 278 flags = Transform::ROT_270; 279 break; 280 default: 281 return BAD_VALUE; 282 } 283 tr->set(flags, w, h); 284 return NO_ERROR; 285} 286 287status_t DisplayDevice::setOrientation(int orientation) { 288 int w = mDisplayWidth; 289 int h = mDisplayHeight; 290 291 DisplayDevice::orientationToTransfrom( 292 orientation, w, h, &mGlobalTransform); 293 if (orientation & DisplayState::eOrientationSwapMask) { 294 int tmp = w; 295 w = h; 296 h = tmp; 297 } 298 mOrientation = orientation; 299 dirtyRegion.set(bounds()); 300 return NO_ERROR; 301} 302