DisplayDevice.cpp revision c7d14e247117392fbd44aa454622778a25c076ae
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <string.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <math.h>
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <cutils/properties.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
24076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <utils/RefBase.h>
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h>
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/PixelFormat.h>
280926f50664c739eaee60341f8e8c694dc9a4f3ebMathias Agopian#include <ui/FramebufferNativeWindow.h>
296cf50a770dabd13cf5b72bb0a6fb9dd002c88db6Mathias Agopian#include <ui/EGLUtils.h>
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <EGL/egl.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <EGL/eglext.h>
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <pixelflinger/pixelflinger.h>
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/gralloc.h>
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
411f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
42a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian#include "HWComposer.h"
43c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian#include "SurfaceFlinger.h"
441f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android;
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid checkGLErrors()
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
51cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    do {
52cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // there could be more than one error flag
53cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        GLenum error = glGetError();
54cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        if (error == GL_NO_ERROR)
55cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            break;
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("GL error 0x%04x", int(error));
57cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } while(true);
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid checkEGLErrors(const char* token)
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLint error = eglGetError();
64cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (error && error != EGL_SUCCESS) {
65cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE("%s: EGL error 0x%04x (%s)",
660928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian                token, int(error), EGLUtils::strerror(error));
67cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Initialize the display to the specified values.
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectDisplayHardware::DisplayHardware(
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<SurfaceFlinger>& flinger,
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t dpy)
781f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    : DisplayHardwareBase(flinger, dpy),
79c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian      mFlinger(flinger), mFlags(0), mHwc(0)
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init(dpy);
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectDisplayHardware::~DisplayHardware()
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    fini();
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat DisplayHardware::getDpiX() const          { return mDpiX; }
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat DisplayHardware::getDpiY() const          { return mDpiY; }
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat DisplayHardware::getDensity() const       { return mDensity; }
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat DisplayHardware::getRefreshRate() const   { return mRefreshRate; }
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint DisplayHardware::getWidth() const           { return mWidth; }
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint DisplayHardware::getHeight() const          { return mHeight; }
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectPixelFormat DisplayHardware::getFormat() const  { return mFormat; }
96ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopianuint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; }
973d64e738b91b2a4a9d81fae1991e6f6eae9ac8c8Mathias Agopian
983d64e738b91b2a4a9d81fae1991e6f6eae9ac8c8Mathias Agopianuint32_t DisplayHardware::getMaxViewportDims() const {
993d64e738b91b2a4a9d81fae1991e6f6eae9ac8c8Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
1003d64e738b91b2a4a9d81fae1991e6f6eae9ac8c8Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
1013d64e738b91b2a4a9d81fae1991e6f6eae9ac8c8Mathias Agopian}
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1036163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopianstatic status_t selectConfigForPixelFormat(
1046163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        EGLDisplay dpy,
1056163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        EGLint const* attrs,
1066163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        PixelFormat format,
1076163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        EGLConfig* outConfig)
1086163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian{
1096163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    EGLConfig config = NULL;
1106163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    EGLint numConfigs = -1, n=0;
1116163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
1126163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
1136163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
1146163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    for (int i=0 ; i<n ; i++) {
1156163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        EGLint nativeVisualId = 0;
1166163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
1176163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
1186163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian            *outConfig = configs[i];
1196163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian            delete [] configs;
1206163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian            return NO_ERROR;
1216163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        }
1226163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    }
1236163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    delete [] configs;
1246163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    return NAME_NOT_FOUND;
1256163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian}
1266163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian
1276163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::init(uint32_t dpy)
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
130076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mNativeWindow = new FramebufferNativeWindow();
1310928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
1321f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    if (!fbDev) {
1331f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        LOGE("Display subsystem failed to initialize. check logs. exiting...");
1341f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian        exit(0);
1351f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian    }
1361f339ff3875afad128a8e16ee6395c5fad295826Mathias Agopian
1376163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    int format;
1386163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    ANativeWindow const * const window = mNativeWindow.get();
1396163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    window->query(window, NATIVE_WINDOW_FORMAT, &format);
1401f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mDpiX = mNativeWindow->xdpi;
1411f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mDpiY = mNativeWindow->ydpi;
1421f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mRefreshRate = fbDev->fps;
143076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1441f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    EGLint w, h, dummy;
1451f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    EGLint numConfigs=0;
1461f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    EGLSurface surface;
1471f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    EGLContext context;
1486163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    EGLBoolean result;
1496163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    status_t err;
1501f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize EGL
152a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    EGLint attribs[] = {
1536163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian            EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
1546163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian            EGL_NONE,               0,
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            EGL_NONE
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    };
157a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian
158a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    // debug: disable h/w rendering
159a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    char property[PROPERTY_VALUE_MAX];
160a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    if (property_get("debug.sf.hw", property, NULL) > 0) {
161a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian        if (atoi(property) == 0) {
162a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian            LOGW("H/W composition disabled");
163a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian            attribs[2] = EGL_CONFIG_CAVEAT;
164a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian            attribs[3] = EGL_SLOW_CONFIG;
165a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian        }
166a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    }
167a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // TODO: all the extensions below should be queried through
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // eglGetProcAddress().
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglInitialize(display, NULL, NULL);
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglGetConfigs(display, NULL, 0, &numConfigs);
174076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1756163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    EGLConfig config = NULL;
1766163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    err = selectConfigForPixelFormat(display, attribs, format, &config);
1776cf50a770dabd13cf5b72bb0a6fb9dd002c88db6Mathias Agopian    LOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
1786cf50a770dabd13cf5b72bb0a6fb9dd002c88db6Mathias Agopian
1790928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    EGLint r,g,b,a;
1800928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);
1810928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
1820928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);
1830928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
1840928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian
1851e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    if (mNativeWindow->isUpdateOnDemand()) {
18695a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        mFlags |= PARTIAL_UPDATES;
1871e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    }
1881e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (dummy == EGL_SLOW_CONFIG)
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFlags |= SLOW_CONFIG;
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Create our main surface
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
1991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &mWidth);
2001f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20295a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian    if (mFlags & PARTIAL_UPDATES) {
20395a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        // if we have partial updates, we definitely don't need to
20495a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian        // preserve the backbuffer, which may be costly.
2050928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian        eglSurfaceAttrib(display, surface,
2060928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian                EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
2070928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian    }
2080928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (dummy == EGL_BUFFER_PRESERVED) {
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFlags |= BUFFER_PRESERVED;
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
215ae71accf63add81ec3d3cd0269536c24db112cabDavid 'Digit' Turner    /* Read density from build-specific ro.sf.lcd_density property
21624e5f5290195e1c02c18730d0639efda65d64914Mathias Agopian     * except if it is overridden by qemu.sf.lcd_density.
217ae71accf63add81ec3d3cd0269536c24db112cabDavid 'Digit' Turner     */
218ae71accf63add81ec3d3cd0269536c24db112cabDavid 'Digit' Turner    if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) {
219ae71accf63add81ec3d3cd0269536c24db112cabDavid 'Digit' Turner        if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
220ae71accf63add81ec3d3cd0269536c24db112cabDavid 'Digit' Turner            LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
221ae71accf63add81ec3d3cd0269536c24db112cabDavid 'Digit' Turner            strcpy(property, "160");
222694e10ba8778dbb3cda9abe106f73ec0f45c8800David 'Digit' Turner        }
22331469e1069a873993ff43dec803bf5f14fad0fb5David 'Digit' Turner    } else {
22431469e1069a873993ff43dec803bf5f14fad0fb5David 'Digit' Turner        /* for the emulator case, reset the dpi values too */
22531469e1069a873993ff43dec803bf5f14fad0fb5David 'Digit' Turner        mDpiX = mDpiY = atoi(property);
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDensity = atoi(property) * (1.0f/160.0f);
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Create our OpenGL ES context
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
23467226814e1b6d1c02079635608444e73ec658837Mathias Agopian
23567226814e1b6d1c02079635608444e73ec658837Mathias Agopian    EGLint contextAttributes[] = {
23667226814e1b6d1c02079635608444e73ec658837Mathias Agopian#ifdef EGL_IMG_context_priority
23767226814e1b6d1c02079635608444e73ec658837Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
23867226814e1b6d1c02079635608444e73ec658837Mathias Agopian#warning "using EGL_IMG_context_priority"
23967226814e1b6d1c02079635608444e73ec658837Mathias Agopian        EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
24067226814e1b6d1c02079635608444e73ec658837Mathias Agopian#endif
24167226814e1b6d1c02079635608444e73ec658837Mathias Agopian#endif
24267226814e1b6d1c02079635608444e73ec658837Mathias Agopian        EGL_NONE, EGL_NONE
24367226814e1b6d1c02079635608444e73ec658837Mathias Agopian    };
24467226814e1b6d1c02079635608444e73ec658837Mathias Agopian    context = eglCreateContext(display, config, NULL, contextAttributes);
24567226814e1b6d1c02079635608444e73ec658837Mathias Agopian
2461f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mDisplay = display;
2471f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mConfig  = config;
2481f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mSurface = surface;
2491f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mContext = context;
2501f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mFormat  = fbDev->format;
2511f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mPageFlipCount = 0;
2521f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Gather OpenGL ES extensions
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2576163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    result = eglMakeCurrent(display, surface, surface, context);
2586163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    if (!result) {
2596163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        LOGE("Couldn't create a working GLES context. check logs. exiting...");
2606163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian        exit(0);
2616163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    }
2621f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
2631f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
2641f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    extensions.initWithGLStrings(
2651f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glGetString(GL_VENDOR),
2661f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glGetString(GL_RENDERER),
2671f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glGetString(GL_VERSION),
2681f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            glGetString(GL_EXTENSIONS),
2691f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            eglQueryString(display, EGL_VENDOR),
2701f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            eglQueryString(display, EGL_VERSION),
2711f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
273ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
2743d64e738b91b2a4a9d81fae1991e6f6eae9ac8c8Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
275ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
276dcaf29af10a3f100f2b8f7a08e9d4b2c656dd1a4Mathias Agopian
2771f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#ifdef EGL_ANDROID_swap_rectangle
2781f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    if (extensions.hasExtension("EGL_ANDROID_swap_rectangle")) {
2791f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        if (eglSetSwapRectangleANDROID(display, surface,
2801f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian                0, 0, mWidth, mHeight) == EGL_TRUE) {
2811f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // This could fail if this extension is not supported by this
2821f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            // specific surface (of config)
2831f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian            mFlags |= SWAP_RECTANGLE;
2841f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        }
285e049a957ce2a529564a1312dca60e86d0bcb0964Andreas Huber    }
2861f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    // when we have the choice between PARTIAL_UPDATES and SWAP_RECTANGLE
2871f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    // choose PARTIAL_UPDATES, which should be more efficient
2881f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    if (mFlags & PARTIAL_UPDATES)
2891f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian        mFlags &= ~SWAP_RECTANGLE;
29054ba51dff21de666c5ae3bf3abd4f0634ebb0676Mathias Agopian#endif
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2921f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("EGL informations:");
2931f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("# of configs : %d", numConfigs);
2941f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("vendor    : %s", extensions.getEglVendor());
2951f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("version   : %s", extensions.getEglVersion());
2961f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("extensions: %s", extensions.getEglExtension());
2971f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
2981f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
2991f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
3001f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("OpenGL informations:");
3011f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("vendor    : %s", extensions.getVendor());
3021f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("renderer  : %s", extensions.getRenderer());
3031f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("version   : %s", extensions.getVersion());
3041f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("extensions: %s", extensions.getExtension());
3051f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
3063d64e738b91b2a4a9d81fae1991e6f6eae9ac8c8Mathias Agopian    LOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
3071f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    LOGI("flags = %08x", mFlags);
308ca99fb8f65f3ea249c56fb6dccefffb54e87696eMathias Agopian
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Unbind the context from this thread
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
311a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
312a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
313a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    // initialize the H/W composer
314c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian    mHwc = new HWComposer(mFlinger);
315a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (mHwc->initCheck() == NO_ERROR) {
316a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwc->setFrameBuffer(mDisplay, mSurface);
317a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
318a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
319a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
320a350ff98692b3a50cad5cc93f9f83221242ca86aMathias AgopianHWComposer& DisplayHardware::getHwComposer() const {
321a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    return *mHwc;
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Clean up.  Throw out our local state.
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (It's entirely possible we'll never get here, since this is meant
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * for real hardware, which doesn't restart.)
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::fini()
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglTerminate(mDisplay);
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::releaseScreen() const
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    DisplayHardwareBase::releaseScreen();
340f5f2712854599b4970643c6000fe6ae950a08ba9Antti Hatala    if (mHwc->initCheck() == NO_ERROR) {
341f5f2712854599b4970643c6000fe6ae950a08ba9Antti Hatala        mHwc->release();
342f5f2712854599b4970643c6000fe6ae950a08ba9Antti Hatala    }
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::acquireScreen() const
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    DisplayHardwareBase::acquireScreen();
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t DisplayHardware::getPageFlipCount() const {
351076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mPageFlipCount;
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35474faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopianstatus_t DisplayHardware::compositionComplete() const {
35574faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian    return mNativeWindow->compositionComplete();
35674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian}
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35835b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopianint DisplayHardware::getCurrentBufferIndex() const {
35935b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian    return mNativeWindow->getCurrentBufferIndex();
36035b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian}
36135b48d10bc9e064201d3d54d2d476314684a7a05Mathias Agopian
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::flip(const Region& dirty) const
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    checkGLErrors();
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLDisplay dpy = mDisplay;
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLSurface surface = mSurface;
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3695e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian#ifdef EGL_ANDROID_swap_rectangle
370df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    if (mFlags & SWAP_RECTANGLE) {
371b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        const Region newDirty(dirty.intersect(bounds()));
372b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        const Rect b(newDirty.getBounds());
373df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian        eglSetSwapRectangleANDROID(dpy, surface,
374df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian                b.left, b.top, b.width(), b.height());
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3765e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian#endif
3775e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian
37895a666b0e001ebf738418b89d8e8fd50b18110f8Mathias Agopian    if (mFlags & PARTIAL_UPDATES) {
37929d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        mNativeWindow->setUpdateRectangle(dirty.getBounds());
3801e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    }
3811e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian
382076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mPageFlipCount++;
383a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
384a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    if (mHwc->initCheck() == NO_ERROR) {
385a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        mHwc->commit();
386a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    } else {
387a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian        eglSwapBuffers(dpy, surface);
388a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian    }
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    checkEGLErrors("eglSwapBuffers");
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // for debugging
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //glClearColor(1,0,0,0);
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //glClear(GL_COLOR_BUFFER_BIT);
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t DisplayHardware::getFlags() const
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mFlags;
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::makeCurrent() const
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
4051d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling
4061d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gillingvoid DisplayHardware::dump(String8& res) const
4071d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling{
4081d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling    mNativeWindow->dump(res);
4091d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling}
410