DisplayDevice.cpp revision e60b0687c8d49871d0c8786cabe6851f7a7783b5
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 int32_t display, int32_t hwcDisplayId, 72 const sp<ANativeWindow>& nativeWindow, 73 const sp<FramebufferSurface>& framebufferSurface, 74 EGLConfig config) 75 : mFlinger(flinger), 76 mId(display), mHwcDisplayId(hwcDisplayId), 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 = mId >= DisplayDevice::DISPLAY_ID_COUNT; 145 146 // initialize the display orientation transform. 147 DisplayDevice::setOrientation(DisplayState::eOrientationDefault); 148} 149 150uint32_t DisplayDevice::getPageFlipCount() const { 151 return mPageFlipCount; 152} 153 154status_t DisplayDevice::compositionComplete() const { 155 if (mFramebufferSurface == NULL) { 156 return NO_ERROR; 157 } 158 return mFramebufferSurface->compositionComplete(); 159} 160 161void DisplayDevice::flip(const Region& dirty) const 162{ 163 checkGLErrors(); 164 165 EGLDisplay dpy = mDisplay; 166 EGLSurface surface = mSurface; 167 168#ifdef EGL_ANDROID_swap_rectangle 169 if (mFlags & SWAP_RECTANGLE) { 170 const Region newDirty(dirty.intersect(bounds())); 171 const Rect b(newDirty.getBounds()); 172 eglSetSwapRectangleANDROID(dpy, surface, 173 b.left, b.top, b.width(), b.height()); 174 } 175#endif 176 177 mPageFlipCount++; 178} 179 180uint32_t DisplayDevice::getFlags() const 181{ 182 return mFlags; 183} 184 185void DisplayDevice::dump(String8& res) const 186{ 187 if (mFramebufferSurface != NULL) { 188 mFramebufferSurface->dump(res); 189 } 190} 191 192void DisplayDevice::makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx) { 193 EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); 194 if (sur != hw->mSurface) { 195 EGLDisplay dpy = eglGetCurrentDisplay(); 196 eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx); 197 } 198} 199 200// ---------------------------------------------------------------------------- 201 202void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { 203 mVisibleLayersSortedByZ = layers; 204 mSecureLayerVisible = false; 205 size_t count = layers.size(); 206 for (size_t i=0 ; i<count ; i++) { 207 if (layers[i]->isSecure()) { 208 mSecureLayerVisible = true; 209 } 210 } 211} 212 213Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const { 214 return mVisibleLayersSortedByZ; 215} 216 217bool DisplayDevice::getSecureLayerVisible() const { 218 return mSecureLayerVisible; 219} 220 221Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 222 Region dirty; 223 const Transform& planeTransform(mGlobalTransform); 224 if (repaintEverything) { 225 dirty.set(getBounds()); 226 } else { 227 dirty = planeTransform.transform(this->dirtyRegion); 228 dirty.andSelf(getBounds()); 229 } 230 return dirty; 231} 232 233// ---------------------------------------------------------------------------- 234 235bool DisplayDevice::canDraw() const { 236 return mScreenAcquired; 237} 238 239void DisplayDevice::releaseScreen() const { 240 mScreenAcquired = false; 241} 242 243void DisplayDevice::acquireScreen() const { 244 mScreenAcquired = true; 245} 246 247bool DisplayDevice::isScreenAcquired() const { 248 return mScreenAcquired; 249} 250 251// ---------------------------------------------------------------------------- 252 253void DisplayDevice::setLayerStack(uint32_t stack) { 254 mLayerStack = stack; 255 dirtyRegion.set(bounds()); 256} 257 258// ---------------------------------------------------------------------------- 259 260status_t DisplayDevice::orientationToTransfrom( 261 int orientation, int w, int h, Transform* tr) 262{ 263 uint32_t flags = 0; 264 switch (orientation) { 265 case DisplayState::eOrientationDefault: 266 flags = Transform::ROT_0; 267 break; 268 case DisplayState::eOrientation90: 269 flags = Transform::ROT_90; 270 break; 271 case DisplayState::eOrientation180: 272 flags = Transform::ROT_180; 273 break; 274 case DisplayState::eOrientation270: 275 flags = Transform::ROT_270; 276 break; 277 default: 278 return BAD_VALUE; 279 } 280 tr->set(flags, w, h); 281 return NO_ERROR; 282} 283 284status_t DisplayDevice::setOrientation(int orientation) { 285 int w = mDisplayWidth; 286 int h = mDisplayHeight; 287 288 DisplayDevice::orientationToTransfrom( 289 orientation, w, h, &mGlobalTransform); 290 if (orientation & DisplayState::eOrientationSwapMask) { 291 int tmp = w; 292 w = h; 293 h = tmp; 294 } 295 mOrientation = orientation; 296 dirtyRegion.set(bounds()); 297 return NO_ERROR; 298} 299