19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <math.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <cutils/properties.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
241473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <utils/RefBase.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
271473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <ui/PixelFormat.h>
28dff8e58d47ede6e748c0b02e128ca33b42a4f362Mathias Agopian#include <ui/FramebufferNativeWindow.h>
29265d9c076a588cf4cd811fbafd999c7ffe36641bMathias Agopian#include <ui/EGLUtils.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <GLES/gl.h>
321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <EGL/egl.h>
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <EGL/eglext.h>
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
351473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <pixelflinger/pixelflinger.h>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "DisplayHardware/DisplayHardware.h"
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <hardware/gralloc.h>
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian#include "GLExtensions.h"
42e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian#include "HWComposer.h"
43a0bd0d84555c8e503e05b60cd959406a47d76f70Mathias Agopian#include "SurfaceFlinger.h"
44781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __attribute__((noinline))
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid checkGLErrors()
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
519779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    do {
529779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        // there could be more than one error flag
539779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        GLenum error = glGetError();
549779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        if (error == GL_NO_ERROR)
559779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian            break;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("GL error 0x%04x", int(error));
579779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    } while(true);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic __attribute__((noinline))
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid checkEGLErrors(const char* token)
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    EGLint error = eglGetError();
649779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    if (error && error != EGL_SUCCESS) {
659779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian        LOGE("%s: EGL error 0x%04x (%s)",
669ca4dd6011e30cbb3bc40cf0bba7d11362b8bc38Mathias Agopian                token, int(error), EGLUtils::strerror(error));
679779b221e999583ff89e0dfc40e56398737adbb3Mathias Agopian    }
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initialize the display to the specified values.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectDisplayHardware::DisplayHardware(
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const sp<SurfaceFlinger>& flinger,
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint32_t dpy)
78781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    : DisplayHardwareBase(flinger, dpy),
79a0bd0d84555c8e503e05b60cd959406a47d76f70Mathias Agopian      mFlinger(flinger), mFlags(0), mHwc(0)
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    init(dpy);
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectDisplayHardware::~DisplayHardware()
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fini();
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfloat DisplayHardware::getDpiX() const          { return mDpiX; }
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfloat DisplayHardware::getDpiY() const          { return mDpiY; }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfloat DisplayHardware::getDensity() const       { return mDensity; }
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectfloat DisplayHardware::getRefreshRate() const   { return mRefreshRate; }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint DisplayHardware::getWidth() const           { return mWidth; }
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint DisplayHardware::getHeight() const          { return mHeight; }
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectPixelFormat DisplayHardware::getFormat() const  { return mFormat; }
96967dce306267109a6e8aec408b65609ac5642a03Mathias Agopianuint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; }
97c94dce521b57763c6ace6cee206214fd476fe8f9Mathias Agopian
98c94dce521b57763c6ace6cee206214fd476fe8f9Mathias Agopianuint32_t DisplayHardware::getMaxViewportDims() const {
99c94dce521b57763c6ace6cee206214fd476fe8f9Mathias Agopian    return mMaxViewportDims[0] < mMaxViewportDims[1] ?
100c94dce521b57763c6ace6cee206214fd476fe8f9Mathias Agopian            mMaxViewportDims[0] : mMaxViewportDims[1];
101c94dce521b57763c6ace6cee206214fd476fe8f9Mathias Agopian}
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1031861786a97209ed75010a54cca5167593dbfec21Mathias Agopianstatic status_t selectConfigForPixelFormat(
1041861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        EGLDisplay dpy,
1051861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        EGLint const* attrs,
1061861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        PixelFormat format,
1071861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        EGLConfig* outConfig)
1081861786a97209ed75010a54cca5167593dbfec21Mathias Agopian{
1091861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    EGLConfig config = NULL;
1101861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    EGLint numConfigs = -1, n=0;
1111861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    eglGetConfigs(dpy, NULL, 0, &numConfigs);
1121861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    EGLConfig* const configs = new EGLConfig[numConfigs];
1131861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
1141861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    for (int i=0 ; i<n ; i++) {
1151861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        EGLint nativeVisualId = 0;
1161861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
1171861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        if (nativeVisualId>0 && format == nativeVisualId) {
1181861786a97209ed75010a54cca5167593dbfec21Mathias Agopian            *outConfig = configs[i];
1191861786a97209ed75010a54cca5167593dbfec21Mathias Agopian            delete [] configs;
1201861786a97209ed75010a54cca5167593dbfec21Mathias Agopian            return NO_ERROR;
1211861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        }
1221861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    }
1231861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    delete [] configs;
1241861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    return NAME_NOT_FOUND;
1251861786a97209ed75010a54cca5167593dbfec21Mathias Agopian}
1261861786a97209ed75010a54cca5167593dbfec21Mathias Agopian
1271861786a97209ed75010a54cca5167593dbfec21Mathias Agopian
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid DisplayHardware::init(uint32_t dpy)
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    mNativeWindow = new FramebufferNativeWindow();
1319ca4dd6011e30cbb3bc40cf0bba7d11362b8bc38Mathias Agopian    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
1320c63ef5091def41e91a2202560c57b2f6caabfbeMathias Agopian    if (!fbDev) {
1330c63ef5091def41e91a2202560c57b2f6caabfbeMathias Agopian        LOGE("Display subsystem failed to initialize. check logs. exiting...");
1340c63ef5091def41e91a2202560c57b2f6caabfbeMathias Agopian        exit(0);
1350c63ef5091def41e91a2202560c57b2f6caabfbeMathias Agopian    }
1360c63ef5091def41e91a2202560c57b2f6caabfbeMathias Agopian
1371861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    int format;
1381861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    ANativeWindow const * const window = mNativeWindow.get();
1391861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    window->query(window, NATIVE_WINDOW_FORMAT, &format);
140781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mDpiX = mNativeWindow->xdpi;
141781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mDpiY = mNativeWindow->ydpi;
142781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mRefreshRate = fbDev->fps;
1431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
144222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian
145222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian/* FIXME: this is a temporary HACK until we are able to report the refresh rate
146222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian * properly from the HAL. The WindowManagerService now relies on this value.
147222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian */
148222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian#ifndef REFRESH_RATE
149222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian    mRefreshRate = fbDev->fps;
150222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian#else
151222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian    mRefreshRate = REFRESH_RATE;
152222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian#warning "refresh rate set via makefile to REFRESH_RATE"
153222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian#endif
154222357f33a105ce08177b94334c7d14af29df8f6Mathias Agopian
155781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    EGLint w, h, dummy;
156781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    EGLint numConfigs=0;
157781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    EGLSurface surface;
158781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    EGLContext context;
1591861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    EGLBoolean result;
1601861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    status_t err;
161781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // initialize EGL
16324d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian    EGLint attribs[] = {
1641861786a97209ed75010a54cca5167593dbfec21Mathias Agopian            EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
1651861786a97209ed75010a54cca5167593dbfec21Mathias Agopian            EGL_NONE,               0,
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            EGL_NONE
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
16824d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian
16924d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian    // debug: disable h/w rendering
17024d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian    char property[PROPERTY_VALUE_MAX];
17124d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian    if (property_get("debug.sf.hw", property, NULL) > 0) {
17224d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian        if (atoi(property) == 0) {
17324d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian            LOGW("H/W composition disabled");
17424d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian            attribs[2] = EGL_CONFIG_CAVEAT;
17524d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian            attribs[3] = EGL_SLOW_CONFIG;
17624d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian        }
17724d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian    }
17824d237db943051942b5966f5e788d67050ec0ba5Mathias Agopian
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // TODO: all the extensions below should be queried through
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // eglGetProcAddress().
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    eglInitialize(display, NULL, NULL);
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    eglGetConfigs(display, NULL, 0, &numConfigs);
1851473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian
1861861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    EGLConfig config = NULL;
1871861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    err = selectConfigForPixelFormat(display, attribs, format, &config);
188265d9c076a588cf4cd811fbafd999c7ffe36641bMathias Agopian    LOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
189265d9c076a588cf4cd811fbafd999c7ffe36641bMathias Agopian
1909ca4dd6011e30cbb3bc40cf0bba7d11362b8bc38Mathias Agopian    EGLint r,g,b,a;
1919ca4dd6011e30cbb3bc40cf0bba7d11362b8bc38Mathias Agopian    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);
1929ca4dd6011e30cbb3bc40cf0bba7d11362b8bc38Mathias Agopian    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
1939ca4dd6011e30cbb3bc40cf0bba7d11362b8bc38Mathias Agopian    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);
1949ca4dd6011e30cbb3bc40cf0bba7d11362b8bc38Mathias Agopian    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
1959ca4dd6011e30cbb3bc40cf0bba7d11362b8bc38Mathias Agopian
19697b8056c3182a973c67d3c1b196150d4b9e30f3aMathias Agopian    if (mNativeWindow->isUpdateOnDemand()) {
197f2d28b74850ea0869aef2ce0727a6abb7b166a5cMathias Agopian        mFlags |= PARTIAL_UPDATES;
19897b8056c3182a973c67d3c1b196150d4b9e30f3aMathias Agopian    }
19997b8056c3182a973c67d3c1b196150d4b9e30f3aMathias Agopian
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dummy == EGL_SLOW_CONFIG)
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFlags |= SLOW_CONFIG;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create our main surface
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2091473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
210781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &mWidth);
211781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
213f2d28b74850ea0869aef2ce0727a6abb7b166a5cMathias Agopian    if (mFlags & PARTIAL_UPDATES) {
214f2d28b74850ea0869aef2ce0727a6abb7b166a5cMathias Agopian        // if we have partial updates, we definitely don't need to
215f2d28b74850ea0869aef2ce0727a6abb7b166a5cMathias Agopian        // preserve the backbuffer, which may be costly.
216af369f6280c9eec0caa3f53f8e27f3713e1a7d25Mathias Agopian        eglSurfaceAttrib(display, surface,
217af369f6280c9eec0caa3f53f8e27f3713e1a7d25Mathias Agopian                EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
218af369f6280c9eec0caa3f53f8e27f3713e1a7d25Mathias Agopian    }
219af369f6280c9eec0caa3f53f8e27f3713e1a7d25Mathias Agopian
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (dummy == EGL_BUFFER_PRESERVED) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFlags |= BUFFER_PRESERVED;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2263c08a446c5b4f2682da1d8461bd1ed94060c29dcDavid 'Digit' Turner    /* Read density from build-specific ro.sf.lcd_density property
22788e3e6bd04dcf166ddd92ce3a84e1f9f54ac2f66Mathias Agopian     * except if it is overridden by qemu.sf.lcd_density.
2283c08a446c5b4f2682da1d8461bd1ed94060c29dcDavid 'Digit' Turner     */
2293c08a446c5b4f2682da1d8461bd1ed94060c29dcDavid 'Digit' Turner    if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) {
2303c08a446c5b4f2682da1d8461bd1ed94060c29dcDavid 'Digit' Turner        if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
2313c08a446c5b4f2682da1d8461bd1ed94060c29dcDavid 'Digit' Turner            LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
2323c08a446c5b4f2682da1d8461bd1ed94060c29dcDavid 'Digit' Turner            strcpy(property, "160");
2332a578ae518ff3d8a2d4768b3d190e4702509e82cDavid 'Digit' Turner        }
234d75fe9aa835b0811911e1727de8e15b329dafd49David 'Digit' Turner    } else {
235d75fe9aa835b0811911e1727de8e15b329dafd49David 'Digit' Turner        /* for the emulator case, reset the dpi values too */
236d75fe9aa835b0811911e1727de8e15b329dafd49David 'Digit' Turner        mDpiX = mDpiY = atoi(property);
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mDensity = atoi(property) * (1.0f/160.0f);
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create our OpenGL ES context
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
245cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian
246cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian    EGLint contextAttributes[] = {
247cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian#ifdef EGL_IMG_context_priority
248cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian#ifdef HAS_CONTEXT_PRIORITY
249cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian#warning "using EGL_IMG_context_priority"
250cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian        EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
251cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian#endif
252cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian#endif
253cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian        EGL_NONE, EGL_NONE
254cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian    };
255cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian    context = eglCreateContext(display, config, NULL, contextAttributes);
256cd54dc26f7ac23da6c920dd83b30242049470f00Mathias Agopian
257781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mDisplay = display;
258781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mConfig  = config;
259781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mSurface = surface;
260781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mContext = context;
261781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mFormat  = fbDev->format;
262781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    mPageFlipCount = 0;
263781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Gather OpenGL ES extensions
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2681861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    result = eglMakeCurrent(display, surface, surface, context);
2691861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    if (!result) {
2701861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        LOGE("Couldn't create a working GLES context. check logs. exiting...");
2711861786a97209ed75010a54cca5167593dbfec21Mathias Agopian        exit(0);
2721861786a97209ed75010a54cca5167593dbfec21Mathias Agopian    }
273781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian
274781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    GLExtensions& extensions(GLExtensions::getInstance());
275781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    extensions.initWithGLStrings(
276781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            glGetString(GL_VENDOR),
277781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            glGetString(GL_RENDERER),
278781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            glGetString(GL_VERSION),
279781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            glGetString(GL_EXTENSIONS),
280781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            eglQueryString(display, EGL_VENDOR),
281781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            eglQueryString(display, EGL_VERSION),
282781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian            eglQueryString(display, EGL_EXTENSIONS));
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
284967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
285c94dce521b57763c6ace6cee206214fd476fe8f9Mathias Agopian    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
286967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian
287781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("EGL informations:");
288781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("# of configs : %d", numConfigs);
289781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("vendor    : %s", extensions.getEglVendor());
290781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("version   : %s", extensions.getEglVersion());
291781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("extensions: %s", extensions.getEglExtension());
292781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
293781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
294781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian
295781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("OpenGL informations:");
296781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("vendor    : %s", extensions.getVendor());
297781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("renderer  : %s", extensions.getRenderer());
298781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("version   : %s", extensions.getVersion());
299781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("extensions: %s", extensions.getExtension());
300781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
301c94dce521b57763c6ace6cee206214fd476fe8f9Mathias Agopian    LOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]);
302781953d62dc17d761e39540f0480e5ca7451cdbeMathias Agopian    LOGI("flags = %08x", mFlags);
303967dce306267109a6e8aec408b65609ac5642a03Mathias Agopian
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Unbind the context from this thread
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
306e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian
307e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian
308e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian    // initialize the H/W composer
309a0bd0d84555c8e503e05b60cd959406a47d76f70Mathias Agopian    mHwc = new HWComposer(mFlinger);
310e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian    if (mHwc->initCheck() == NO_ERROR) {
311e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian        mHwc->setFrameBuffer(mDisplay, mSurface);
312e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian    }
313e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian}
314e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian
315e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias AgopianHWComposer& DisplayHardware::getHwComposer() const {
316e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian    return *mHwc;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Clean up.  Throw out our local state.
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (It's entirely possible we'll never get here, since this is meant
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for real hardware, which doesn't restart.)
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid DisplayHardware::fini()
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    eglTerminate(mDisplay);
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid DisplayHardware::releaseScreen() const
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DisplayHardwareBase::releaseScreen();
33511042a41c1fe1415df0f45ef5fd3905d34b6e01aAntti Hatala    if (mHwc->initCheck() == NO_ERROR) {
33611042a41c1fe1415df0f45ef5fd3905d34b6e01aAntti Hatala        mHwc->release();
33711042a41c1fe1415df0f45ef5fd3905d34b6e01aAntti Hatala    }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid DisplayHardware::acquireScreen() const
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    DisplayHardwareBase::acquireScreen();
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t DisplayHardware::getPageFlipCount() const {
3461473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    return mPageFlipCount;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349b1a1874625a6aca967601fcda53a82d8d712df45Mathias Agopianstatus_t DisplayHardware::compositionComplete() const {
350b1a1874625a6aca967601fcda53a82d8d712df45Mathias Agopian    return mNativeWindow->compositionComplete();
351b1a1874625a6aca967601fcda53a82d8d712df45Mathias Agopian}
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
35304262e9f842edf20168399b6a70f0d67e518fe69Mathias Agopianint DisplayHardware::getCurrentBufferIndex() const {
35404262e9f842edf20168399b6a70f0d67e518fe69Mathias Agopian    return mNativeWindow->getCurrentBufferIndex();
35504262e9f842edf20168399b6a70f0d67e518fe69Mathias Agopian}
35604262e9f842edf20168399b6a70f0d67e518fe69Mathias Agopian
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid DisplayHardware::flip(const Region& dirty) const
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    checkGLErrors();
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    EGLDisplay dpy = mDisplay;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    EGLSurface surface = mSurface;
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
364e19476214a2fe718c82461f54e6b56cee7faa5f4Mathias Agopian#ifdef EGL_ANDROID_swap_rectangle
3652e20bffbab8084fedce39d14d7dd17b08f6e9ba2Mathias Agopian    if (mFlags & SWAP_RECTANGLE) {
3668c9687ae291a1e0a63d4236069066284f56192cdMathias Agopian        const Region newDirty(dirty.intersect(bounds()));
3678c9687ae291a1e0a63d4236069066284f56192cdMathias Agopian        const Rect b(newDirty.getBounds());
3682e20bffbab8084fedce39d14d7dd17b08f6e9ba2Mathias Agopian        eglSetSwapRectangleANDROID(dpy, surface,
3692e20bffbab8084fedce39d14d7dd17b08f6e9ba2Mathias Agopian                b.left, b.top, b.width(), b.height());
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
371e19476214a2fe718c82461f54e6b56cee7faa5f4Mathias Agopian#endif
372e19476214a2fe718c82461f54e6b56cee7faa5f4Mathias Agopian
373f2d28b74850ea0869aef2ce0727a6abb7b166a5cMathias Agopian    if (mFlags & PARTIAL_UPDATES) {
374ecfa7ccd4fc3066a4cfd4d84d7de286d95581c78Mathias Agopian        mNativeWindow->setUpdateRectangle(dirty.getBounds());
37597b8056c3182a973c67d3c1b196150d4b9e30f3aMathias Agopian    }
37697b8056c3182a973c67d3c1b196150d4b9e30f3aMathias Agopian
3771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    mPageFlipCount++;
378e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian
379e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian    if (mHwc->initCheck() == NO_ERROR) {
380e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian        mHwc->commit();
381e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian    } else {
382e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian        eglSwapBuffers(dpy, surface);
383e0d5f5bcf5a8b26f4ad75f549cbf380b2c9faf20Mathias Agopian    }
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    checkEGLErrors("eglSwapBuffers");
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // for debugging
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //glClearColor(1,0,0,0);
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    //glClear(GL_COLOR_BUFFER_BIT);
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t DisplayHardware::getFlags() const
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mFlags;
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid DisplayHardware::makeCurrent() const
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
40094720d7ec40d2b5ee200d95a46588cdb0fb30e66Erik Gilling
40194720d7ec40d2b5ee200d95a46588cdb0fb30e66Erik Gillingvoid DisplayHardware::dump(String8& res) const
40294720d7ec40d2b5ee200d95a46588cdb0fb30e66Erik Gilling{
40394720d7ec40d2b5ee200d95a46588cdb0fb30e66Erik Gilling    mNativeWindow->dump(res);
40494720d7ec40d2b5ee200d95a46588cdb0fb30e66Erik Gilling}
405