| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 17 | #include <stdlib.h> | 
|  | 18 | #include <stdio.h> | 
|  | 19 | #include <string.h> | 
|  | 20 | #include <math.h> | 
|  | 21 |  | 
|  | 22 | #include <cutils/properties.h> | 
|  | 23 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 24 | #include <utils/RefBase.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 25 | #include <utils/Log.h> | 
|  | 26 |  | 
| Mathias Agopian | c666cae | 2012-07-25 18:56:13 -0700 | [diff] [blame] | 27 | #include <ui/DisplayInfo.h> | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 28 | #include <ui/PixelFormat.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 29 |  | 
|  | 30 | #include <GLES/gl.h> | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 31 | #include <EGL/egl.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 32 | #include <EGL/eglext.h> | 
|  | 33 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 34 | #include <hardware/gralloc.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 35 |  | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 36 | #include "DisplayHardware/FramebufferSurface.h" | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 37 | #include "DisplayHardware/HWComposer.h" | 
|  | 38 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 39 | #include "DisplayDevice.h" | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 40 | #include "GLExtensions.h" | 
| Mathias Agopian | c7d14e2 | 2011-08-01 16:32:21 -0700 | [diff] [blame] | 41 | #include "SurfaceFlinger.h" | 
| Mathias Agopian | 921e6ac | 2012-07-23 23:11:29 -0700 | [diff] [blame] | 42 | #include "LayerBase.h" | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 43 |  | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 44 | // ---------------------------------------------------------------------------- | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 45 | using namespace android; | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 46 | // ---------------------------------------------------------------------------- | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 47 |  | 
|  | 48 | static __attribute__((noinline)) | 
|  | 49 | void checkGLErrors() | 
|  | 50 | { | 
| Mathias Agopian | cbb288b | 2009-09-07 16:32:45 -0700 | [diff] [blame] | 51 | do { | 
|  | 52 | // there could be more than one error flag | 
|  | 53 | GLenum error = glGetError(); | 
|  | 54 | if (error == GL_NO_ERROR) | 
|  | 55 | break; | 
| Steve Block | e6f43dd | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 56 | ALOGE("GL error 0x%04x", int(error)); | 
| Mathias Agopian | cbb288b | 2009-09-07 16:32:45 -0700 | [diff] [blame] | 57 | } while(true); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 58 | } | 
|  | 59 |  | 
|  | 60 | static __attribute__((noinline)) | 
|  | 61 | void checkEGLErrors(const char* token) | 
|  | 62 | { | 
| Mathias Agopian | 870b8aa | 2012-02-24 16:42:46 -0800 | [diff] [blame] | 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 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 86 | EGLint error = eglGetError(); | 
| Mathias Agopian | cbb288b | 2009-09-07 16:32:45 -0700 | [diff] [blame] | 87 | if (error && error != EGL_SUCCESS) { | 
| Steve Block | e6f43dd | 2012-01-06 19:20:56 +0000 | [diff] [blame] | 88 | ALOGE("%s: EGL error 0x%04x (%s)", | 
| Mathias Agopian | 0928e31 | 2009-08-07 16:38:10 -0700 | [diff] [blame] | 89 | token, int(error), EGLUtils::strerror(error)); | 
| Mathias Agopian | cbb288b | 2009-09-07 16:32:45 -0700 | [diff] [blame] | 90 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 91 | } | 
|  | 92 |  | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 93 | // ---------------------------------------------------------------------------- | 
|  | 94 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 95 | /* | 
|  | 96 | * Initialize the display to the specified values. | 
|  | 97 | * | 
|  | 98 | */ | 
|  | 99 |  | 
| Mathias Agopian | 92a979a | 2012-08-02 18:32:23 -0700 | [diff] [blame^] | 100 | DisplayDevice::DisplayDevice() | 
|  | 101 | : mId(0), | 
|  | 102 | mDisplay(EGL_NO_DISPLAY), | 
|  | 103 | mSurface(EGL_NO_SURFACE), | 
|  | 104 | mContext(EGL_NO_CONTEXT) | 
|  | 105 | { | 
|  | 106 | } | 
|  | 107 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 108 | DisplayDevice::DisplayDevice( | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 109 | const sp<SurfaceFlinger>& flinger, | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 110 | int display, | 
|  | 111 | const sp<SurfaceTextureClient>& surface, | 
|  | 112 | EGLConfig config) | 
| Mathias Agopian | 92a979a | 2012-08-02 18:32:23 -0700 | [diff] [blame^] | 113 | : mFlinger(flinger), | 
|  | 114 | mId(display), | 
|  | 115 | mNativeWindow(surface), | 
|  | 116 | mDisplay(EGL_NO_DISPLAY), | 
|  | 117 | mSurface(EGL_NO_SURFACE), | 
|  | 118 | mContext(EGL_NO_CONTEXT), | 
|  | 119 | mDpiX(), mDpiY(), | 
|  | 120 | mRefreshRate(), | 
|  | 121 | mDensity(), | 
|  | 122 | mDisplayWidth(), mDisplayHeight(), mFormat(), | 
|  | 123 | mFlags(), | 
|  | 124 | mPageFlipCount(), | 
|  | 125 | mRefreshPeriod(), | 
|  | 126 | mSecureLayerVisible(false), | 
|  | 127 | mScreenAcquired(false), | 
|  | 128 | mOrientation(), | 
|  | 129 | mLayerStack(0) | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 130 | { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 131 | init(config); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 132 | } | 
|  | 133 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 134 | DisplayDevice::~DisplayDevice() { | 
| Mathias Agopian | 92a979a | 2012-08-02 18:32:23 -0700 | [diff] [blame^] | 135 | // DO NOT call terminate() from here, because we create | 
|  | 136 | // temporaries of this class (on the stack typically), and we don't | 
|  | 137 | // want to destroy the EGLSurface in that case | 
|  | 138 | } | 
|  | 139 |  | 
|  | 140 | void DisplayDevice::terminate() { | 
|  | 141 | if (mSurface != EGL_NO_SURFACE) { | 
|  | 142 | eglDestroySurface(mDisplay, mSurface); | 
|  | 143 | mSurface = EGL_NO_SURFACE; | 
|  | 144 | } | 
|  | 145 | } | 
|  | 146 |  | 
|  | 147 | bool DisplayDevice::isValid() const { | 
|  | 148 | return mFlinger != NULL; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 149 | } | 
|  | 150 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 151 | float DisplayDevice::getDpiX() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 152 | return mDpiX; | 
| Mathias Agopian | 3d64e73 | 2011-04-18 15:59:24 -0700 | [diff] [blame] | 153 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 154 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 155 | float DisplayDevice::getDpiY() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 156 | return mDpiY; | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 157 | } | 
|  | 158 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 159 | float DisplayDevice::getDensity() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 160 | return mDensity; | 
|  | 161 | } | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 162 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 163 | float DisplayDevice::getRefreshRate() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 164 | return mRefreshRate; | 
|  | 165 | } | 
|  | 166 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 167 | int DisplayDevice::getWidth() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 168 | return mDisplayWidth; | 
|  | 169 | } | 
|  | 170 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 171 | int DisplayDevice::getHeight() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 172 | return mDisplayHeight; | 
|  | 173 | } | 
|  | 174 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 175 | PixelFormat DisplayDevice::getFormat() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 176 | return mFormat; | 
|  | 177 | } | 
|  | 178 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 179 | EGLSurface DisplayDevice::getEGLSurface() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 180 | return mSurface; | 
|  | 181 | } | 
|  | 182 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 183 | status_t DisplayDevice::getInfo(DisplayInfo* info) const { | 
| Mathias Agopian | c666cae | 2012-07-25 18:56:13 -0700 | [diff] [blame] | 184 | info->w = getWidth(); | 
|  | 185 | info->h = getHeight(); | 
|  | 186 | info->xdpi = getDpiX(); | 
|  | 187 | info->ydpi = getDpiY(); | 
|  | 188 | info->fps = getRefreshRate(); | 
|  | 189 | info->density = getDensity(); | 
|  | 190 | info->orientation = getOrientation(); | 
|  | 191 | // TODO: this needs to go away (currently needed only by webkit) | 
|  | 192 | getPixelFormatInfo(getFormat(), &info->pixelFormatInfo); | 
|  | 193 | return NO_ERROR; | 
|  | 194 | } | 
|  | 195 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 196 | void DisplayDevice::init(EGLConfig config) | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 197 | { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 198 | ANativeWindow* const window = mNativeWindow.get(); | 
|  | 199 |  | 
|  | 200 | int concreteType; | 
|  | 201 | window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &concreteType); | 
|  | 202 | if (concreteType == NATIVE_WINDOW_FRAMEBUFFER) { | 
|  | 203 | mFramebufferSurface = static_cast<FramebufferSurface *>(mNativeWindow.get()); | 
| Mathias Agopian | 1f339ff | 2011-07-01 17:08:43 -0700 | [diff] [blame] | 204 | } | 
|  | 205 |  | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 206 | int format; | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 207 | window->query(window, NATIVE_WINDOW_FORMAT, &format); | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 208 | mDpiX = window->xdpi; | 
|  | 209 | mDpiY = window->ydpi; | 
|  | 210 | if (mFramebufferSurface != NULL) { | 
|  | 211 | mRefreshRate = mFramebufferSurface->getRefreshRate(); | 
|  | 212 | } else { | 
|  | 213 | mRefreshRate = 60; | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 214 | } | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 215 | mRefreshPeriod = nsecs_t(1e9 / mRefreshRate); | 
| Mathias Agopian | 385977f | 2011-11-04 18:46:11 -0700 | [diff] [blame] | 216 |  | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 217 |  | 
|  | 218 | // TODO: Not sure if display density should handled by SF any longer | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 219 | class Density { | 
|  | 220 | static int getDensityFromProperty(char const* propName) { | 
|  | 221 | char property[PROPERTY_VALUE_MAX]; | 
|  | 222 | int density = 0; | 
|  | 223 | if (property_get(propName, property, NULL) > 0) { | 
|  | 224 | density = atoi(property); | 
|  | 225 | } | 
|  | 226 | return density; | 
|  | 227 | } | 
|  | 228 | public: | 
|  | 229 | static int getEmuDensity() { | 
|  | 230 | return getDensityFromProperty("qemu.sf.lcd_density"); } | 
|  | 231 | static int getBuildDensity()  { | 
|  | 232 | return getDensityFromProperty("ro.sf.lcd_density"); } | 
|  | 233 | }; | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 234 | // The density of the device is provided by a build property | 
|  | 235 | mDensity = Density::getBuildDensity() / 160.0f; | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 236 | if (mDensity == 0) { | 
|  | 237 | // the build doesn't provide a density -- this is wrong! | 
|  | 238 | // use xdpi instead | 
|  | 239 | ALOGE("ro.sf.lcd_density must be defined as a build property"); | 
|  | 240 | mDensity = mDpiX / 160.0f; | 
|  | 241 | } | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 242 | if (Density::getEmuDensity()) { | 
|  | 243 | // if "qemu.sf.lcd_density" is specified, it overrides everything | 
|  | 244 | mDpiX = mDpiY = mDensity = Density::getEmuDensity(); | 
|  | 245 | mDensity /= 160.0f; | 
|  | 246 | } | 
|  | 247 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 248 | /* | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 249 | * Create our display's surface | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 250 | */ | 
|  | 251 |  | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 252 | EGLSurface surface; | 
|  | 253 | EGLint w, h; | 
|  | 254 | EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 
|  | 255 | surface = eglCreateWindowSurface(display, config, window, NULL); | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 256 | eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth); | 
|  | 257 | eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 258 |  | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 259 | if (mFramebufferSurface != NULL) { | 
|  | 260 | if (mFramebufferSurface->isUpdateOnDemand()) { | 
|  | 261 | mFlags |= PARTIAL_UPDATES; | 
|  | 262 | // if we have partial updates, we definitely don't need to | 
|  | 263 | // preserve the backbuffer, which may be costly. | 
|  | 264 | eglSurfaceAttrib(display, surface, | 
|  | 265 | EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); | 
|  | 266 | } | 
| Mathias Agopian | 0928bee | 2009-09-16 20:15:42 -0700 | [diff] [blame] | 267 | } | 
|  | 268 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 269 | mDisplay = display; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 270 | mSurface = surface; | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 271 | mFormat  = format; | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 272 | mPageFlipCount = 0; | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 273 |  | 
| Mathias Agopian | 98a121a | 2012-07-24 21:08:59 -0700 | [diff] [blame] | 274 | // initialize the display orientation transform. | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 275 | DisplayDevice::setOrientation(ISurfaceComposer::eOrientationDefault); | 
| Mathias Agopian | a350ff9 | 2010-08-10 17:14:02 -0700 | [diff] [blame] | 276 | } | 
|  | 277 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 278 | uint32_t DisplayDevice::getPageFlipCount() const { | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 279 | return mPageFlipCount; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 280 | } | 
|  | 281 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 282 | nsecs_t DisplayDevice::getRefreshPeriod() const { | 
| Mathias Agopian | 82d7ab6 | 2012-01-19 18:34:40 -0800 | [diff] [blame] | 283 | return mRefreshPeriod; | 
|  | 284 | } | 
|  | 285 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 286 | status_t DisplayDevice::compositionComplete() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 287 | if (mFramebufferSurface == NULL) { | 
|  | 288 | return NO_ERROR; | 
|  | 289 | } | 
|  | 290 | return mFramebufferSurface->compositionComplete(); | 
| Mathias Agopian | 74faca2 | 2009-09-17 16:18:16 -0700 | [diff] [blame] | 291 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 292 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 293 | void DisplayDevice::flip(const Region& dirty) const | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 294 | { | 
|  | 295 | checkGLErrors(); | 
|  | 296 |  | 
|  | 297 | EGLDisplay dpy = mDisplay; | 
|  | 298 | EGLSurface surface = mSurface; | 
|  | 299 |  | 
| Mathias Agopian | 5e78e09 | 2009-06-11 17:19:54 -0700 | [diff] [blame] | 300 | #ifdef EGL_ANDROID_swap_rectangle | 
| Mathias Agopian | df3ca30 | 2009-05-04 19:29:25 -0700 | [diff] [blame] | 301 | if (mFlags & SWAP_RECTANGLE) { | 
| Mathias Agopian | b8a5560 | 2009-06-26 19:06:36 -0700 | [diff] [blame] | 302 | const Region newDirty(dirty.intersect(bounds())); | 
|  | 303 | const Rect b(newDirty.getBounds()); | 
| Mathias Agopian | df3ca30 | 2009-05-04 19:29:25 -0700 | [diff] [blame] | 304 | eglSetSwapRectangleANDROID(dpy, surface, | 
|  | 305 | b.left, b.top, b.width(), b.height()); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 306 | } | 
| Mathias Agopian | 5e78e09 | 2009-06-11 17:19:54 -0700 | [diff] [blame] | 307 | #endif | 
|  | 308 |  | 
| Mathias Agopian | 95a666b | 2009-09-24 14:57:26 -0700 | [diff] [blame] | 309 | if (mFlags & PARTIAL_UPDATES) { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 310 | if (mFramebufferSurface != NULL) { | 
|  | 311 | mFramebufferSurface->setUpdateRectangle(dirty.getBounds()); | 
|  | 312 | } | 
| Mathias Agopian | 1e16b13 | 2009-05-07 17:40:23 -0700 | [diff] [blame] | 313 | } | 
|  | 314 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 315 | mPageFlipCount++; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 316 | } | 
|  | 317 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 318 | uint32_t DisplayDevice::getFlags() const | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 319 | { | 
|  | 320 | return mFlags; | 
|  | 321 | } | 
|  | 322 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 323 | void DisplayDevice::dump(String8& res) const | 
| Erik Gilling | 1d21a9c | 2010-12-01 16:38:01 -0800 | [diff] [blame] | 324 | { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 325 | if (mFramebufferSurface != NULL) { | 
|  | 326 | mFramebufferSurface->dump(res); | 
|  | 327 | } | 
| Erik Gilling | 1d21a9c | 2010-12-01 16:38:01 -0800 | [diff] [blame] | 328 | } | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 329 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 330 | void DisplayDevice::makeCurrent(const DisplayDevice& hw, EGLContext ctx) { | 
| Mathias Agopian | 52bbb1a | 2012-07-31 19:01:53 -0700 | [diff] [blame] | 331 | EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); | 
|  | 332 | if (sur != hw.mSurface) { | 
|  | 333 | EGLDisplay dpy = eglGetCurrentDisplay(); | 
|  | 334 | eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx); | 
|  | 335 | } | 
|  | 336 | } | 
|  | 337 |  | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 338 | // ---------------------------------------------------------------------------- | 
|  | 339 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 340 | void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { | 
| Mathias Agopian | 3b1d2b6 | 2012-07-11 13:48:17 -0700 | [diff] [blame] | 341 | mVisibleLayersSortedByZ = layers; | 
|  | 342 | size_t count = layers.size(); | 
|  | 343 | for (size_t i=0 ; i<count ; i++) { | 
|  | 344 | if (layers[i]->isSecure()) { | 
|  | 345 | mSecureLayerVisible = true; | 
|  | 346 | } | 
|  | 347 | } | 
|  | 348 | } | 
|  | 349 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 350 | Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const { | 
| Mathias Agopian | 3b1d2b6 | 2012-07-11 13:48:17 -0700 | [diff] [blame] | 351 | return mVisibleLayersSortedByZ; | 
|  | 352 | } | 
|  | 353 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 354 | bool DisplayDevice::getSecureLayerVisible() const { | 
| Mathias Agopian | 3b1d2b6 | 2012-07-11 13:48:17 -0700 | [diff] [blame] | 355 | return mSecureLayerVisible; | 
|  | 356 | } | 
|  | 357 |  | 
|  | 358 | // ---------------------------------------------------------------------------- | 
|  | 359 |  | 
| Mathias Agopian | d3ee231 | 2012-08-02 14:01:42 -0700 | [diff] [blame] | 360 | bool DisplayDevice::canDraw() const { | 
|  | 361 | return mScreenAcquired; | 
|  | 362 | } | 
|  | 363 |  | 
|  | 364 | void DisplayDevice::releaseScreen() const { | 
|  | 365 | mScreenAcquired = false; | 
|  | 366 | } | 
|  | 367 |  | 
|  | 368 | void DisplayDevice::acquireScreen() const { | 
|  | 369 | mScreenAcquired = true; | 
|  | 370 | } | 
|  | 371 |  | 
|  | 372 | bool DisplayDevice::isScreenAcquired() const { | 
|  | 373 | return mScreenAcquired; | 
|  | 374 | } | 
|  | 375 |  | 
|  | 376 | // ---------------------------------------------------------------------------- | 
|  | 377 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 378 | status_t DisplayDevice::orientationToTransfrom( | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 379 | int orientation, int w, int h, Transform* tr) | 
|  | 380 | { | 
|  | 381 | uint32_t flags = 0; | 
|  | 382 | switch (orientation) { | 
|  | 383 | case ISurfaceComposer::eOrientationDefault: | 
|  | 384 | flags = Transform::ROT_0; | 
|  | 385 | break; | 
|  | 386 | case ISurfaceComposer::eOrientation90: | 
|  | 387 | flags = Transform::ROT_90; | 
|  | 388 | break; | 
|  | 389 | case ISurfaceComposer::eOrientation180: | 
|  | 390 | flags = Transform::ROT_180; | 
|  | 391 | break; | 
|  | 392 | case ISurfaceComposer::eOrientation270: | 
|  | 393 | flags = Transform::ROT_270; | 
|  | 394 | break; | 
|  | 395 | default: | 
|  | 396 | return BAD_VALUE; | 
|  | 397 | } | 
|  | 398 | tr->set(flags, w, h); | 
|  | 399 | return NO_ERROR; | 
|  | 400 | } | 
|  | 401 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 402 | status_t DisplayDevice::setOrientation(int orientation) { | 
| Mathias Agopian | 98a121a | 2012-07-24 21:08:59 -0700 | [diff] [blame] | 403 | int w = mDisplayWidth; | 
|  | 404 | int h = mDisplayHeight; | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 405 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 406 | DisplayDevice::orientationToTransfrom( | 
| Mathias Agopian | 98a121a | 2012-07-24 21:08:59 -0700 | [diff] [blame] | 407 | orientation, w, h, &mGlobalTransform); | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 408 | if (orientation & ISurfaceComposer::eOrientationSwapMask) { | 
| Mathias Agopian | 98a121a | 2012-07-24 21:08:59 -0700 | [diff] [blame] | 409 | int tmp = w; | 
|  | 410 | w = h; | 
|  | 411 | h = tmp; | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 412 | } | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 413 | mOrientation = orientation; | 
| Mathias Agopian | 92a979a | 2012-08-02 18:32:23 -0700 | [diff] [blame^] | 414 | dirtyRegion.set(bounds()); | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 415 | return NO_ERROR; | 
|  | 416 | } |