| 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, | 
| Mathias Agopian | d8552d7 | 2012-08-04 21:39:11 -0700 | [diff] [blame^] | 111 |         const sp<ANativeWindow>& surface, | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 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(), | 
| Mathias Agopian | 92a979a | 2012-08-02 18:32:23 -0700 | [diff] [blame] | 120 |       mDensity(), | 
 | 121 |       mDisplayWidth(), mDisplayHeight(), mFormat(), | 
 | 122 |       mFlags(), | 
 | 123 |       mPageFlipCount(), | 
| Mathias Agopian | 92a979a | 2012-08-02 18:32:23 -0700 | [diff] [blame] | 124 |       mSecureLayerVisible(false), | 
 | 125 |       mScreenAcquired(false), | 
 | 126 |       mOrientation(), | 
 | 127 |       mLayerStack(0) | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 128 | { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 129 |     init(config); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 130 | } | 
 | 131 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 132 | DisplayDevice::~DisplayDevice() { | 
| Mathias Agopian | 92a979a | 2012-08-02 18:32:23 -0700 | [diff] [blame] | 133 |     // DO NOT call terminate() from here, because we create | 
 | 134 |     // temporaries of this class (on the stack typically), and we don't | 
 | 135 |     // want to destroy the EGLSurface in that case | 
 | 136 | } | 
 | 137 |  | 
 | 138 | void DisplayDevice::terminate() { | 
 | 139 |     if (mSurface != EGL_NO_SURFACE) { | 
 | 140 |         eglDestroySurface(mDisplay, mSurface); | 
 | 141 |         mSurface = EGL_NO_SURFACE; | 
 | 142 |     } | 
 | 143 | } | 
 | 144 |  | 
 | 145 | bool DisplayDevice::isValid() const { | 
 | 146 |     return mFlinger != NULL; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 147 | } | 
 | 148 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 149 | float DisplayDevice::getDpiX() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 150 |     return mDpiX; | 
| Mathias Agopian | 3d64e73 | 2011-04-18 15:59:24 -0700 | [diff] [blame] | 151 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 152 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 153 | float DisplayDevice::getDpiY() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 154 |     return mDpiY; | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 155 | } | 
 | 156 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 157 | float DisplayDevice::getDensity() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 158 |     return mDensity; | 
 | 159 | } | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 160 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 161 | int DisplayDevice::getWidth() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 162 |     return mDisplayWidth; | 
 | 163 | } | 
 | 164 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 165 | int DisplayDevice::getHeight() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 166 |     return mDisplayHeight; | 
 | 167 | } | 
 | 168 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 169 | PixelFormat DisplayDevice::getFormat() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 170 |     return mFormat; | 
 | 171 | } | 
 | 172 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 173 | EGLSurface DisplayDevice::getEGLSurface() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 174 |     return mSurface; | 
 | 175 | } | 
 | 176 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 177 | void DisplayDevice::init(EGLConfig config) | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 178 | { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 179 |     ANativeWindow* const window = mNativeWindow.get(); | 
 | 180 |  | 
 | 181 |     int concreteType; | 
 | 182 |     window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &concreteType); | 
 | 183 |     if (concreteType == NATIVE_WINDOW_FRAMEBUFFER) { | 
 | 184 |         mFramebufferSurface = static_cast<FramebufferSurface *>(mNativeWindow.get()); | 
| Mathias Agopian | 1f339ff | 2011-07-01 17:08:43 -0700 | [diff] [blame] | 185 |     } | 
 | 186 |  | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 187 |     int format; | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 188 |     window->query(window, NATIVE_WINDOW_FORMAT, &format); | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 189 |     mDpiX = window->xdpi; | 
 | 190 |     mDpiY = window->ydpi; | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 191 |  | 
 | 192 |     // TODO: Not sure if display density should handled by SF any longer | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 193 |     class Density { | 
 | 194 |         static int getDensityFromProperty(char const* propName) { | 
 | 195 |             char property[PROPERTY_VALUE_MAX]; | 
 | 196 |             int density = 0; | 
 | 197 |             if (property_get(propName, property, NULL) > 0) { | 
 | 198 |                 density = atoi(property); | 
 | 199 |             } | 
 | 200 |             return density; | 
 | 201 |         } | 
 | 202 |     public: | 
 | 203 |         static int getEmuDensity() { | 
 | 204 |             return getDensityFromProperty("qemu.sf.lcd_density"); } | 
 | 205 |         static int getBuildDensity()  { | 
 | 206 |             return getDensityFromProperty("ro.sf.lcd_density"); } | 
 | 207 |     }; | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 208 |     // The density of the device is provided by a build property | 
 | 209 |     mDensity = Density::getBuildDensity() / 160.0f; | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 210 |     if (mDensity == 0) { | 
 | 211 |         // the build doesn't provide a density -- this is wrong! | 
 | 212 |         // use xdpi instead | 
 | 213 |         ALOGE("ro.sf.lcd_density must be defined as a build property"); | 
 | 214 |         mDensity = mDpiX / 160.0f; | 
 | 215 |     } | 
| Mathias Agopian | b5dd9c0 | 2012-03-22 12:15:54 -0700 | [diff] [blame] | 216 |     if (Density::getEmuDensity()) { | 
 | 217 |         // if "qemu.sf.lcd_density" is specified, it overrides everything | 
 | 218 |         mDpiX = mDpiY = mDensity = Density::getEmuDensity(); | 
 | 219 |         mDensity /= 160.0f; | 
 | 220 |     } | 
 | 221 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 222 |     /* | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 223 |      * Create our display's surface | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 224 |      */ | 
 | 225 |  | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 226 |     EGLSurface surface; | 
 | 227 |     EGLint w, h; | 
 | 228 |     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 
 | 229 |     surface = eglCreateWindowSurface(display, config, window, NULL); | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 230 |     eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth); | 
 | 231 |     eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 232 |  | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 233 |     if (mFramebufferSurface != NULL) { | 
 | 234 |         if (mFramebufferSurface->isUpdateOnDemand()) { | 
 | 235 |             mFlags |= PARTIAL_UPDATES; | 
 | 236 |             // if we have partial updates, we definitely don't need to | 
 | 237 |             // preserve the backbuffer, which may be costly. | 
 | 238 |             eglSurfaceAttrib(display, surface, | 
 | 239 |                     EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); | 
 | 240 |         } | 
| Mathias Agopian | 0928bee | 2009-09-16 20:15:42 -0700 | [diff] [blame] | 241 |     } | 
 | 242 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 243 |     mDisplay = display; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 244 |     mSurface = surface; | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 245 |     mFormat  = format; | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 246 |     mPageFlipCount = 0; | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 247 |  | 
| Mathias Agopian | 98a121a | 2012-07-24 21:08:59 -0700 | [diff] [blame] | 248 |     // initialize the display orientation transform. | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 249 |     DisplayDevice::setOrientation(ISurfaceComposer::eOrientationDefault); | 
| Mathias Agopian | a350ff9 | 2010-08-10 17:14:02 -0700 | [diff] [blame] | 250 | } | 
 | 251 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 252 | uint32_t DisplayDevice::getPageFlipCount() const { | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 253 |     return mPageFlipCount; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 254 | } | 
 | 255 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 256 | status_t DisplayDevice::compositionComplete() const { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 257 |     if (mFramebufferSurface == NULL) { | 
 | 258 |         return NO_ERROR; | 
 | 259 |     } | 
 | 260 |     return mFramebufferSurface->compositionComplete(); | 
| Mathias Agopian | 74faca2 | 2009-09-17 16:18:16 -0700 | [diff] [blame] | 261 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 262 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 263 | void DisplayDevice::flip(const Region& dirty) const | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 264 | { | 
 | 265 |     checkGLErrors(); | 
 | 266 |  | 
 | 267 |     EGLDisplay dpy = mDisplay; | 
 | 268 |     EGLSurface surface = mSurface; | 
 | 269 |  | 
| Mathias Agopian | 5e78e09 | 2009-06-11 17:19:54 -0700 | [diff] [blame] | 270 | #ifdef EGL_ANDROID_swap_rectangle     | 
| Mathias Agopian | df3ca30 | 2009-05-04 19:29:25 -0700 | [diff] [blame] | 271 |     if (mFlags & SWAP_RECTANGLE) { | 
| Mathias Agopian | b8a5560 | 2009-06-26 19:06:36 -0700 | [diff] [blame] | 272 |         const Region newDirty(dirty.intersect(bounds())); | 
 | 273 |         const Rect b(newDirty.getBounds()); | 
| Mathias Agopian | df3ca30 | 2009-05-04 19:29:25 -0700 | [diff] [blame] | 274 |         eglSetSwapRectangleANDROID(dpy, surface, | 
 | 275 |                 b.left, b.top, b.width(), b.height()); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 276 |     }  | 
| Mathias Agopian | 5e78e09 | 2009-06-11 17:19:54 -0700 | [diff] [blame] | 277 | #endif | 
 | 278 |      | 
| Mathias Agopian | 95a666b | 2009-09-24 14:57:26 -0700 | [diff] [blame] | 279 |     if (mFlags & PARTIAL_UPDATES) { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 280 |         if (mFramebufferSurface != NULL) { | 
 | 281 |             mFramebufferSurface->setUpdateRectangle(dirty.getBounds()); | 
 | 282 |         } | 
| Mathias Agopian | 1e16b13 | 2009-05-07 17:40:23 -0700 | [diff] [blame] | 283 |     } | 
 | 284 |      | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 285 |     mPageFlipCount++; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 286 | } | 
 | 287 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 288 | uint32_t DisplayDevice::getFlags() const | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 289 | { | 
 | 290 |     return mFlags; | 
 | 291 | } | 
 | 292 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 293 | void DisplayDevice::dump(String8& res) const | 
| Erik Gilling | 1d21a9c | 2010-12-01 16:38:01 -0800 | [diff] [blame] | 294 | { | 
| Mathias Agopian | a491260 | 2012-07-12 14:25:33 -0700 | [diff] [blame] | 295 |     if (mFramebufferSurface != NULL) { | 
 | 296 |         mFramebufferSurface->dump(res); | 
 | 297 |     } | 
| Erik Gilling | 1d21a9c | 2010-12-01 16:38:01 -0800 | [diff] [blame] | 298 | } | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 299 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 300 | void DisplayDevice::makeCurrent(const DisplayDevice& hw, EGLContext ctx) { | 
| Mathias Agopian | 52bbb1a | 2012-07-31 19:01:53 -0700 | [diff] [blame] | 301 |     EGLSurface sur = eglGetCurrentSurface(EGL_DRAW); | 
 | 302 |     if (sur != hw.mSurface) { | 
 | 303 |         EGLDisplay dpy = eglGetCurrentDisplay(); | 
 | 304 |         eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx); | 
 | 305 |     } | 
 | 306 | } | 
 | 307 |  | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 308 | // ---------------------------------------------------------------------------- | 
 | 309 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 310 | void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { | 
| Mathias Agopian | 3b1d2b6 | 2012-07-11 13:48:17 -0700 | [diff] [blame] | 311 |     mVisibleLayersSortedByZ = layers; | 
 | 312 |     size_t count = layers.size(); | 
 | 313 |     for (size_t i=0 ; i<count ; i++) { | 
 | 314 |         if (layers[i]->isSecure()) { | 
 | 315 |             mSecureLayerVisible = true; | 
 | 316 |         } | 
 | 317 |     } | 
 | 318 | } | 
 | 319 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 320 | Vector< sp<LayerBase> > DisplayDevice::getVisibleLayersSortedByZ() const { | 
| Mathias Agopian | 3b1d2b6 | 2012-07-11 13:48:17 -0700 | [diff] [blame] | 321 |     return mVisibleLayersSortedByZ; | 
 | 322 | } | 
 | 323 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 324 | bool DisplayDevice::getSecureLayerVisible() const { | 
| Mathias Agopian | 3b1d2b6 | 2012-07-11 13:48:17 -0700 | [diff] [blame] | 325 |     return mSecureLayerVisible; | 
 | 326 | } | 
 | 327 |  | 
 | 328 | // ---------------------------------------------------------------------------- | 
 | 329 |  | 
| Mathias Agopian | d3ee231 | 2012-08-02 14:01:42 -0700 | [diff] [blame] | 330 | bool DisplayDevice::canDraw() const { | 
 | 331 |     return mScreenAcquired; | 
 | 332 | } | 
 | 333 |  | 
 | 334 | void DisplayDevice::releaseScreen() const { | 
 | 335 |     mScreenAcquired = false; | 
 | 336 | } | 
 | 337 |  | 
 | 338 | void DisplayDevice::acquireScreen() const { | 
 | 339 |     mScreenAcquired = true; | 
 | 340 | } | 
 | 341 |  | 
 | 342 | bool DisplayDevice::isScreenAcquired() const { | 
 | 343 |     return mScreenAcquired; | 
 | 344 | } | 
 | 345 |  | 
 | 346 | // ---------------------------------------------------------------------------- | 
 | 347 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 348 | status_t DisplayDevice::orientationToTransfrom( | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 349 |         int orientation, int w, int h, Transform* tr) | 
 | 350 | { | 
 | 351 |     uint32_t flags = 0; | 
 | 352 |     switch (orientation) { | 
 | 353 |     case ISurfaceComposer::eOrientationDefault: | 
 | 354 |         flags = Transform::ROT_0; | 
 | 355 |         break; | 
 | 356 |     case ISurfaceComposer::eOrientation90: | 
 | 357 |         flags = Transform::ROT_90; | 
 | 358 |         break; | 
 | 359 |     case ISurfaceComposer::eOrientation180: | 
 | 360 |         flags = Transform::ROT_180; | 
 | 361 |         break; | 
 | 362 |     case ISurfaceComposer::eOrientation270: | 
 | 363 |         flags = Transform::ROT_270; | 
 | 364 |         break; | 
 | 365 |     default: | 
 | 366 |         return BAD_VALUE; | 
 | 367 |     } | 
 | 368 |     tr->set(flags, w, h); | 
 | 369 |     return NO_ERROR; | 
 | 370 | } | 
 | 371 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 372 | status_t DisplayDevice::setOrientation(int orientation) { | 
| Mathias Agopian | 98a121a | 2012-07-24 21:08:59 -0700 | [diff] [blame] | 373 |     int w = mDisplayWidth; | 
 | 374 |     int h = mDisplayHeight; | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 375 |  | 
| Mathias Agopian | 0f2f5ff | 2012-07-31 23:09:07 -0700 | [diff] [blame] | 376 |     DisplayDevice::orientationToTransfrom( | 
| Mathias Agopian | 98a121a | 2012-07-24 21:08:59 -0700 | [diff] [blame] | 377 |             orientation, w, h, &mGlobalTransform); | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 378 |     if (orientation & ISurfaceComposer::eOrientationSwapMask) { | 
| Mathias Agopian | 98a121a | 2012-07-24 21:08:59 -0700 | [diff] [blame] | 379 |         int tmp = w; | 
 | 380 |         w = h; | 
 | 381 |         h = tmp; | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 382 |     } | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 383 |     mOrientation = orientation; | 
| Mathias Agopian | 92a979a | 2012-08-02 18:32:23 -0700 | [diff] [blame] | 384 |     dirtyRegion.set(bounds()); | 
| Mathias Agopian | 1b03149 | 2012-06-20 17:51:20 -0700 | [diff] [blame] | 385 |     return NO_ERROR; | 
 | 386 | } |