| 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 | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 27 | #include <ui/PixelFormat.h> | 
| Mathias Agopian | 0926f50 | 2009-05-04 14:17:04 -0700 | [diff] [blame] | 28 | #include <ui/FramebufferNativeWindow.h> | 
| Mathias Agopian | 6cf50a7 | 2009-08-06 16:05:39 -0700 | [diff] [blame] | 29 | #include <ui/EGLUtils.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 30 |  | 
|  | 31 | #include <GLES/gl.h> | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 32 | #include <EGL/egl.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 33 | #include <EGL/eglext.h> | 
|  | 34 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 35 | #include <pixelflinger/pixelflinger.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 36 |  | 
|  | 37 | #include "DisplayHardware/DisplayHardware.h" | 
|  | 38 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 39 | #include <hardware/gralloc.h> | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 40 |  | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 41 | #include "GLExtensions.h" | 
| Mathias Agopian | a350ff9 | 2010-08-10 17:14:02 -0700 | [diff] [blame] | 42 | #include "HWComposer.h" | 
| Mathias Agopian | c7d14e2 | 2011-08-01 16:32:21 -0700 | [diff] [blame] | 43 | #include "SurfaceFlinger.h" | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 44 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 45 | using namespace android; | 
|  | 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; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 56 | LOGE("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 | { | 
|  | 63 | EGLint error = eglGetError(); | 
| Mathias Agopian | cbb288b | 2009-09-07 16:32:45 -0700 | [diff] [blame] | 64 | if (error && error != EGL_SUCCESS) { | 
|  | 65 | LOGE("%s: EGL error 0x%04x (%s)", | 
| Mathias Agopian | 0928e31 | 2009-08-07 16:38:10 -0700 | [diff] [blame] | 66 | token, int(error), EGLUtils::strerror(error)); | 
| Mathias Agopian | cbb288b | 2009-09-07 16:32:45 -0700 | [diff] [blame] | 67 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 68 | } | 
|  | 69 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 70 | /* | 
|  | 71 | * Initialize the display to the specified values. | 
|  | 72 | * | 
|  | 73 | */ | 
|  | 74 |  | 
|  | 75 | DisplayHardware::DisplayHardware( | 
|  | 76 | const sp<SurfaceFlinger>& flinger, | 
|  | 77 | uint32_t dpy) | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 78 | : DisplayHardwareBase(flinger, dpy), | 
| Mathias Agopian | c7d14e2 | 2011-08-01 16:32:21 -0700 | [diff] [blame] | 79 | mFlinger(flinger), mFlags(0), mHwc(0) | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 80 | { | 
|  | 81 | init(dpy); | 
|  | 82 | } | 
|  | 83 |  | 
|  | 84 | DisplayHardware::~DisplayHardware() | 
|  | 85 | { | 
|  | 86 | fini(); | 
|  | 87 | } | 
|  | 88 |  | 
|  | 89 | float DisplayHardware::getDpiX() const          { return mDpiX; } | 
|  | 90 | float DisplayHardware::getDpiY() const          { return mDpiY; } | 
|  | 91 | float DisplayHardware::getDensity() const       { return mDensity; } | 
|  | 92 | float DisplayHardware::getRefreshRate() const   { return mRefreshRate; } | 
|  | 93 | int DisplayHardware::getWidth() const           { return mWidth; } | 
|  | 94 | int DisplayHardware::getHeight() const          { return mHeight; } | 
|  | 95 | PixelFormat DisplayHardware::getFormat() const  { return mFormat; } | 
| Mathias Agopian | ca99fb8 | 2010-04-14 16:43:44 -0700 | [diff] [blame] | 96 | uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; } | 
| Mathias Agopian | 3d64e73 | 2011-04-18 15:59:24 -0700 | [diff] [blame] | 97 |  | 
|  | 98 | uint32_t DisplayHardware::getMaxViewportDims() const { | 
|  | 99 | return mMaxViewportDims[0] < mMaxViewportDims[1] ? | 
|  | 100 | mMaxViewportDims[0] : mMaxViewportDims[1]; | 
|  | 101 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 102 |  | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 103 | static status_t selectConfigForPixelFormat( | 
|  | 104 | EGLDisplay dpy, | 
|  | 105 | EGLint const* attrs, | 
|  | 106 | PixelFormat format, | 
|  | 107 | EGLConfig* outConfig) | 
|  | 108 | { | 
|  | 109 | EGLConfig config = NULL; | 
|  | 110 | EGLint numConfigs = -1, n=0; | 
|  | 111 | eglGetConfigs(dpy, NULL, 0, &numConfigs); | 
|  | 112 | EGLConfig* const configs = new EGLConfig[numConfigs]; | 
|  | 113 | eglChooseConfig(dpy, attrs, configs, numConfigs, &n); | 
|  | 114 | for (int i=0 ; i<n ; i++) { | 
|  | 115 | EGLint nativeVisualId = 0; | 
|  | 116 | eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); | 
|  | 117 | if (nativeVisualId>0 && format == nativeVisualId) { | 
|  | 118 | *outConfig = configs[i]; | 
|  | 119 | delete [] configs; | 
|  | 120 | return NO_ERROR; | 
|  | 121 | } | 
|  | 122 | } | 
|  | 123 | delete [] configs; | 
|  | 124 | return NAME_NOT_FOUND; | 
|  | 125 | } | 
|  | 126 |  | 
|  | 127 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 128 | void DisplayHardware::init(uint32_t dpy) | 
|  | 129 | { | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 130 | mNativeWindow = new FramebufferNativeWindow(); | 
| Mathias Agopian | 0928e31 | 2009-08-07 16:38:10 -0700 | [diff] [blame] | 131 | framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); | 
| Mathias Agopian | 1f339ff | 2011-07-01 17:08:43 -0700 | [diff] [blame] | 132 | if (!fbDev) { | 
|  | 133 | LOGE("Display subsystem failed to initialize. check logs. exiting..."); | 
|  | 134 | exit(0); | 
|  | 135 | } | 
|  | 136 |  | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 137 | int format; | 
|  | 138 | ANativeWindow const * const window = mNativeWindow.get(); | 
|  | 139 | window->query(window, NATIVE_WINDOW_FORMAT, &format); | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 140 | mDpiX = mNativeWindow->xdpi; | 
|  | 141 | mDpiY = mNativeWindow->ydpi; | 
|  | 142 | mRefreshRate = fbDev->fps; | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 143 |  | 
| Mathias Agopian | 385977f | 2011-11-04 18:46:11 -0700 | [diff] [blame] | 144 |  | 
|  | 145 | /* FIXME: this is a temporary HACK until we are able to report the refresh rate | 
|  | 146 | * properly from the HAL. The WindowManagerService now relies on this value. | 
|  | 147 | */ | 
|  | 148 | #ifndef REFRESH_RATE | 
|  | 149 | mRefreshRate = fbDev->fps; | 
|  | 150 | #else | 
|  | 151 | mRefreshRate = REFRESH_RATE; | 
|  | 152 | #warning "refresh rate set via makefile to REFRESH_RATE" | 
|  | 153 | #endif | 
|  | 154 |  | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 155 | EGLint w, h, dummy; | 
|  | 156 | EGLint numConfigs=0; | 
|  | 157 | EGLSurface surface; | 
|  | 158 | EGLContext context; | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 159 | EGLBoolean result; | 
|  | 160 | status_t err; | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 161 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 162 | // initialize EGL | 
| Mathias Agopian | a5b02e0 | 2009-09-04 18:49:03 -0700 | [diff] [blame] | 163 | EGLint attribs[] = { | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 164 | EGL_SURFACE_TYPE,       EGL_WINDOW_BIT, | 
|  | 165 | EGL_NONE,               0, | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 166 | EGL_NONE | 
|  | 167 | }; | 
| Mathias Agopian | a5b02e0 | 2009-09-04 18:49:03 -0700 | [diff] [blame] | 168 |  | 
|  | 169 | // debug: disable h/w rendering | 
|  | 170 | char property[PROPERTY_VALUE_MAX]; | 
|  | 171 | if (property_get("debug.sf.hw", property, NULL) > 0) { | 
|  | 172 | if (atoi(property) == 0) { | 
|  | 173 | LOGW("H/W composition disabled"); | 
|  | 174 | attribs[2] = EGL_CONFIG_CAVEAT; | 
|  | 175 | attribs[3] = EGL_SLOW_CONFIG; | 
|  | 176 | } | 
|  | 177 | } | 
|  | 178 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 179 | // TODO: all the extensions below should be queried through | 
|  | 180 | // eglGetProcAddress(). | 
|  | 181 |  | 
|  | 182 | EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 
|  | 183 | eglInitialize(display, NULL, NULL); | 
|  | 184 | eglGetConfigs(display, NULL, 0, &numConfigs); | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 185 |  | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 186 | EGLConfig config = NULL; | 
|  | 187 | err = selectConfigForPixelFormat(display, attribs, format, &config); | 
| Mathias Agopian | 6cf50a7 | 2009-08-06 16:05:39 -0700 | [diff] [blame] | 188 | LOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); | 
|  | 189 |  | 
| Mathias Agopian | 0928e31 | 2009-08-07 16:38:10 -0700 | [diff] [blame] | 190 | EGLint r,g,b,a; | 
|  | 191 | eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r); | 
|  | 192 | eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g); | 
|  | 193 | eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b); | 
|  | 194 | eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a); | 
|  | 195 |  | 
| Mathias Agopian | 1e16b13 | 2009-05-07 17:40:23 -0700 | [diff] [blame] | 196 | if (mNativeWindow->isUpdateOnDemand()) { | 
| Mathias Agopian | 95a666b | 2009-09-24 14:57:26 -0700 | [diff] [blame] | 197 | mFlags |= PARTIAL_UPDATES; | 
| Mathias Agopian | 1e16b13 | 2009-05-07 17:40:23 -0700 | [diff] [blame] | 198 | } | 
|  | 199 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 200 | if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { | 
|  | 201 | if (dummy == EGL_SLOW_CONFIG) | 
|  | 202 | mFlags |= SLOW_CONFIG; | 
|  | 203 | } | 
|  | 204 |  | 
|  | 205 | /* | 
|  | 206 | * Create our main surface | 
|  | 207 | */ | 
|  | 208 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 209 | surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 210 | eglQuerySurface(display, surface, EGL_WIDTH,  &mWidth); | 
|  | 211 | eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 212 |  | 
| Mathias Agopian | 95a666b | 2009-09-24 14:57:26 -0700 | [diff] [blame] | 213 | if (mFlags & PARTIAL_UPDATES) { | 
|  | 214 | // if we have partial updates, we definitely don't need to | 
|  | 215 | // preserve the backbuffer, which may be costly. | 
| Mathias Agopian | 0928bee | 2009-09-16 20:15:42 -0700 | [diff] [blame] | 216 | eglSurfaceAttrib(display, surface, | 
|  | 217 | EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); | 
|  | 218 | } | 
|  | 219 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 220 | if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) { | 
|  | 221 | if (dummy == EGL_BUFFER_PRESERVED) { | 
|  | 222 | mFlags |= BUFFER_PRESERVED; | 
|  | 223 | } | 
|  | 224 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 225 |  | 
| David 'Digit' Turner | ae71acc | 2009-06-19 04:41:12 +0200 | [diff] [blame] | 226 | /* Read density from build-specific ro.sf.lcd_density property | 
| Mathias Agopian | 24e5f52 | 2009-08-12 21:18:15 -0700 | [diff] [blame] | 227 | * except if it is overridden by qemu.sf.lcd_density. | 
| David 'Digit' Turner | ae71acc | 2009-06-19 04:41:12 +0200 | [diff] [blame] | 228 | */ | 
|  | 229 | if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) { | 
|  | 230 | if (property_get("ro.sf.lcd_density", property, NULL) <= 0) { | 
|  | 231 | LOGW("ro.sf.lcd_density not defined, using 160 dpi by default."); | 
|  | 232 | strcpy(property, "160"); | 
| David 'Digit' Turner | 694e10b | 2009-06-18 04:30:32 +0200 | [diff] [blame] | 233 | } | 
| David 'Digit' Turner | 31469e1 | 2009-07-29 00:38:58 +0200 | [diff] [blame] | 234 | } else { | 
|  | 235 | /* for the emulator case, reset the dpi values too */ | 
|  | 236 | mDpiX = mDpiY = atoi(property); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 237 | } | 
|  | 238 | mDensity = atoi(property) * (1.0f/160.0f); | 
|  | 239 |  | 
|  | 240 |  | 
|  | 241 | /* | 
|  | 242 | * Create our OpenGL ES context | 
|  | 243 | */ | 
|  | 244 |  | 
| Mathias Agopian | 6722681 | 2010-10-11 17:54:43 -0700 | [diff] [blame] | 245 |  | 
|  | 246 | EGLint contextAttributes[] = { | 
|  | 247 | #ifdef EGL_IMG_context_priority | 
|  | 248 | #ifdef HAS_CONTEXT_PRIORITY | 
|  | 249 | #warning "using EGL_IMG_context_priority" | 
|  | 250 | EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, | 
|  | 251 | #endif | 
|  | 252 | #endif | 
|  | 253 | EGL_NONE, EGL_NONE | 
|  | 254 | }; | 
|  | 255 | context = eglCreateContext(display, config, NULL, contextAttributes); | 
|  | 256 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 257 | mDisplay = display; | 
|  | 258 | mConfig  = config; | 
|  | 259 | mSurface = surface; | 
|  | 260 | mContext = context; | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 261 | mFormat  = fbDev->format; | 
|  | 262 | mPageFlipCount = 0; | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 263 |  | 
|  | 264 | /* | 
|  | 265 | * Gather OpenGL ES extensions | 
|  | 266 | */ | 
|  | 267 |  | 
| Mathias Agopian | 6163091 | 2011-07-06 16:35:30 -0700 | [diff] [blame] | 268 | result = eglMakeCurrent(display, surface, surface, context); | 
|  | 269 | if (!result) { | 
|  | 270 | LOGE("Couldn't create a working GLES context. check logs. exiting..."); | 
|  | 271 | exit(0); | 
|  | 272 | } | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 273 |  | 
|  | 274 | GLExtensions& extensions(GLExtensions::getInstance()); | 
|  | 275 | extensions.initWithGLStrings( | 
|  | 276 | glGetString(GL_VENDOR), | 
|  | 277 | glGetString(GL_RENDERER), | 
|  | 278 | glGetString(GL_VERSION), | 
|  | 279 | glGetString(GL_EXTENSIONS), | 
|  | 280 | eglQueryString(display, EGL_VENDOR), | 
|  | 281 | eglQueryString(display, EGL_VERSION), | 
|  | 282 | eglQueryString(display, EGL_EXTENSIONS)); | 
|  | 283 |  | 
|  | 284 | glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); | 
| Mathias Agopian | 3d64e73 | 2011-04-18 15:59:24 -0700 | [diff] [blame] | 285 | glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 286 |  | 
| Steve Block | 5b11920 | 2012-01-04 20:05:49 +0000 | [diff] [blame^] | 287 | ALOGI("EGL informations:"); | 
|  | 288 | ALOGI("# of configs : %d", numConfigs); | 
|  | 289 | ALOGI("vendor    : %s", extensions.getEglVendor()); | 
|  | 290 | ALOGI("version   : %s", extensions.getEglVersion()); | 
|  | 291 | ALOGI("extensions: %s", extensions.getEglExtension()); | 
|  | 292 | ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); | 
|  | 293 | ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config); | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 294 |  | 
| Steve Block | 5b11920 | 2012-01-04 20:05:49 +0000 | [diff] [blame^] | 295 | ALOGI("OpenGL informations:"); | 
|  | 296 | ALOGI("vendor    : %s", extensions.getVendor()); | 
|  | 297 | ALOGI("renderer  : %s", extensions.getRenderer()); | 
|  | 298 | ALOGI("version   : %s", extensions.getVersion()); | 
|  | 299 | ALOGI("extensions: %s", extensions.getExtension()); | 
|  | 300 | ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); | 
|  | 301 | ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); | 
|  | 302 | ALOGI("flags = %08x", mFlags); | 
| Mathias Agopian | 1f7bec6 | 2010-06-25 18:02:21 -0700 | [diff] [blame] | 303 |  | 
|  | 304 | // Unbind the context from this thread | 
|  | 305 | eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | 
| Mathias Agopian | a350ff9 | 2010-08-10 17:14:02 -0700 | [diff] [blame] | 306 |  | 
|  | 307 |  | 
|  | 308 | // initialize the H/W composer | 
| Mathias Agopian | c7d14e2 | 2011-08-01 16:32:21 -0700 | [diff] [blame] | 309 | mHwc = new HWComposer(mFlinger); | 
| Mathias Agopian | a350ff9 | 2010-08-10 17:14:02 -0700 | [diff] [blame] | 310 | if (mHwc->initCheck() == NO_ERROR) { | 
|  | 311 | mHwc->setFrameBuffer(mDisplay, mSurface); | 
|  | 312 | } | 
|  | 313 | } | 
|  | 314 |  | 
|  | 315 | HWComposer& DisplayHardware::getHwComposer() const { | 
|  | 316 | return *mHwc; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 317 | } | 
|  | 318 |  | 
|  | 319 | /* | 
|  | 320 | * Clean up.  Throw out our local state. | 
|  | 321 | * | 
|  | 322 | * (It's entirely possible we'll never get here, since this is meant | 
|  | 323 | * for real hardware, which doesn't restart.) | 
|  | 324 | */ | 
|  | 325 |  | 
|  | 326 | void DisplayHardware::fini() | 
|  | 327 | { | 
|  | 328 | eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | 
|  | 329 | eglTerminate(mDisplay); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 330 | } | 
|  | 331 |  | 
|  | 332 | void DisplayHardware::releaseScreen() const | 
|  | 333 | { | 
|  | 334 | DisplayHardwareBase::releaseScreen(); | 
| Antti Hatala | f5f2712 | 2010-09-09 02:33:05 -0700 | [diff] [blame] | 335 | if (mHwc->initCheck() == NO_ERROR) { | 
|  | 336 | mHwc->release(); | 
|  | 337 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 338 | } | 
|  | 339 |  | 
|  | 340 | void DisplayHardware::acquireScreen() const | 
|  | 341 | { | 
|  | 342 | DisplayHardwareBase::acquireScreen(); | 
|  | 343 | } | 
|  | 344 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 345 | uint32_t DisplayHardware::getPageFlipCount() const { | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 346 | return mPageFlipCount; | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 347 | } | 
|  | 348 |  | 
| Mathias Agopian | 74faca2 | 2009-09-17 16:18:16 -0700 | [diff] [blame] | 349 | status_t DisplayHardware::compositionComplete() const { | 
|  | 350 | return mNativeWindow->compositionComplete(); | 
|  | 351 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 352 |  | 
| Mathias Agopian | 35b48d1 | 2010-09-13 22:57:58 -0700 | [diff] [blame] | 353 | int DisplayHardware::getCurrentBufferIndex() const { | 
|  | 354 | return mNativeWindow->getCurrentBufferIndex(); | 
|  | 355 | } | 
|  | 356 |  | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 357 | void DisplayHardware::flip(const Region& dirty) const | 
|  | 358 | { | 
|  | 359 | checkGLErrors(); | 
|  | 360 |  | 
|  | 361 | EGLDisplay dpy = mDisplay; | 
|  | 362 | EGLSurface surface = mSurface; | 
|  | 363 |  | 
| Mathias Agopian | 5e78e09 | 2009-06-11 17:19:54 -0700 | [diff] [blame] | 364 | #ifdef EGL_ANDROID_swap_rectangle | 
| Mathias Agopian | df3ca30 | 2009-05-04 19:29:25 -0700 | [diff] [blame] | 365 | if (mFlags & SWAP_RECTANGLE) { | 
| Mathias Agopian | b8a5560 | 2009-06-26 19:06:36 -0700 | [diff] [blame] | 366 | const Region newDirty(dirty.intersect(bounds())); | 
|  | 367 | const Rect b(newDirty.getBounds()); | 
| Mathias Agopian | df3ca30 | 2009-05-04 19:29:25 -0700 | [diff] [blame] | 368 | eglSetSwapRectangleANDROID(dpy, surface, | 
|  | 369 | b.left, b.top, b.width(), b.height()); | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 370 | } | 
| Mathias Agopian | 5e78e09 | 2009-06-11 17:19:54 -0700 | [diff] [blame] | 371 | #endif | 
|  | 372 |  | 
| Mathias Agopian | 95a666b | 2009-09-24 14:57:26 -0700 | [diff] [blame] | 373 | if (mFlags & PARTIAL_UPDATES) { | 
| Mathias Agopian | 29d06ac | 2009-06-29 18:49:56 -0700 | [diff] [blame] | 374 | mNativeWindow->setUpdateRectangle(dirty.getBounds()); | 
| Mathias Agopian | 1e16b13 | 2009-05-07 17:40:23 -0700 | [diff] [blame] | 375 | } | 
|  | 376 |  | 
| Mathias Agopian | 076b1cc | 2009-04-10 14:24:30 -0700 | [diff] [blame] | 377 | mPageFlipCount++; | 
| Mathias Agopian | a350ff9 | 2010-08-10 17:14:02 -0700 | [diff] [blame] | 378 |  | 
|  | 379 | if (mHwc->initCheck() == NO_ERROR) { | 
|  | 380 | mHwc->commit(); | 
|  | 381 | } else { | 
|  | 382 | eglSwapBuffers(dpy, surface); | 
|  | 383 | } | 
| The Android Open Source Project | edbf3b6 | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 384 | checkEGLErrors("eglSwapBuffers"); | 
|  | 385 |  | 
|  | 386 | // for debugging | 
|  | 387 | //glClearColor(1,0,0,0); | 
|  | 388 | //glClear(GL_COLOR_BUFFER_BIT); | 
|  | 389 | } | 
|  | 390 |  | 
|  | 391 | uint32_t DisplayHardware::getFlags() const | 
|  | 392 | { | 
|  | 393 | return mFlags; | 
|  | 394 | } | 
|  | 395 |  | 
|  | 396 | void DisplayHardware::makeCurrent() const | 
|  | 397 | { | 
|  | 398 | eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); | 
|  | 399 | } | 
| Erik Gilling | 1d21a9c | 2010-12-01 16:38:01 -0800 | [diff] [blame] | 400 |  | 
|  | 401 | void DisplayHardware::dump(String8& res) const | 
|  | 402 | { | 
|  | 403 | mNativeWindow->dump(res); | 
|  | 404 | } |