DisplayDevice.cpp revision 74faca212e2675aa55a30235c77cb6403471a4b9
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
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <hardware/copybit.h>
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <hardware/overlay.h>
41076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/gralloc.h>
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android;
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid checkGLErrors()
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
49cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    do {
50cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // there could be more than one error flag
51cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        GLenum error = glGetError();
52cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        if (error == GL_NO_ERROR)
53cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            break;
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        LOGE("GL error 0x%04x", int(error));
55cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } while(true);
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid checkEGLErrors(const char* token)
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLint error = eglGetError();
62cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    if (error && error != EGL_SUCCESS) {
63cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        LOGE("%s: EGL error 0x%04x (%s)",
640928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian                token, int(error), EGLUtils::strerror(error));
65cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    }
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Initialize the display to the specified values.
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectDisplayHardware::DisplayHardware(
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<SurfaceFlinger>& flinger,
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t dpy)
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    : DisplayHardwareBase(flinger, dpy)
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init(dpy);
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectDisplayHardware::~DisplayHardware()
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    fini();
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat DisplayHardware::getDpiX() const          { return mDpiX; }
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat DisplayHardware::getDpiY() const          { return mDpiY; }
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat DisplayHardware::getDensity() const       { return mDensity; }
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectfloat DisplayHardware::getRefreshRate() const   { return mRefreshRate; }
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint DisplayHardware::getWidth() const           { return mWidth; }
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint DisplayHardware::getHeight() const          { return mHeight; }
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectPixelFormat DisplayHardware::getFormat() const  { return mFormat; }
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::init(uint32_t dpy)
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
96076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mNativeWindow = new FramebufferNativeWindow();
970928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
98076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
99076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mOverlayEngine = NULL;
1000928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    hw_module_t const* module;
101076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
102076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        overlay_control_open(module, &mOverlayEngine);
103076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    }
104076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // initialize EGL
106a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    EGLint attribs[] = {
1070928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian            EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
108a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian            EGL_NONE,           0,
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            EGL_NONE
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    };
111a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian
112a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    // debug: disable h/w rendering
113a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    char property[PROPERTY_VALUE_MAX];
114a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    if (property_get("debug.sf.hw", property, NULL) > 0) {
115a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian        if (atoi(property) == 0) {
116a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian            LOGW("H/W composition disabled");
117a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian            attribs[2] = EGL_CONFIG_CAVEAT;
118a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian            attribs[3] = EGL_SLOW_CONFIG;
119a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian        }
120a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian    }
121a5b02e0b4dfc9947e373e17a383b397f6fcb751cMathias Agopian
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLint w, h, dummy;
1230928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    EGLint numConfigs=0;
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLSurface surface;
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLContext context;
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mFlags = 0;
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // TODO: all the extensions below should be queried through
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // eglGetProcAddress().
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglInitialize(display, NULL, NULL);
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglGetConfigs(display, NULL, 0, &numConfigs);
134076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian
1356cf50a770dabd13cf5b72bb0a6fb9dd002c88db6Mathias Agopian    EGLConfig config;
1360928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    status_t err = EGLUtils::selectConfigForNativeWindow(
1370928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian            display, attribs, mNativeWindow.get(), &config);
1386cf50a770dabd13cf5b72bb0a6fb9dd002c88db6Mathias Agopian    LOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
1396cf50a770dabd13cf5b72bb0a6fb9dd002c88db6Mathias Agopian
1400928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    EGLint r,g,b,a;
1410928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);
1420928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
1430928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);
1440928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
1450928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Gather EGL extensions
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char* const egl_extensions = eglQueryString(
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            display, EGL_EXTENSIONS);
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("EGL informations:");
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("# of configs : %d", numConfigs);
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("vendor    : %s", eglQueryString(display, EGL_VENDOR));
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("version   : %s", eglQueryString(display, EGL_VERSION));
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("extensions: %s", egl_extensions);
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
1590928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian    LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
1600928e31cc7a9ec7367a68796fcaa9c52959216a5Mathias Agopian
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1621e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    if (mNativeWindow->isUpdateOnDemand()) {
1631e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian        mFlags |= UPDATE_ON_DEMAND;
1641e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    }
1651e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (dummy == EGL_SLOW_CONFIG)
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFlags |= SLOW_CONFIG;
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Create our main surface
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
175076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1770928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian    if (mFlags & UPDATE_ON_DEMAND) {
1780928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian        // if we have update on demand, we definitely don't need to
1790928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian        // preserve the backbuffer, which is usually costly.
1800928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian        eglSurfaceAttrib(display, surface,
1810928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian                EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
1820928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian    }
1830928bee979c8fa157e13e37e52ba9ad94e935237Mathias Agopian
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (dummy == EGL_BUFFER_PRESERVED) {
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            mFlags |= BUFFER_PRESERVED;
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
189df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
1908458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &mWidth);
1918458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
1928458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian
1935e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian#ifdef EGL_ANDROID_swap_rectangle
194e6bf8b32b616450f80b64d226ea673f4a2e0bf8dMathias Agopian    if (strstr(egl_extensions, "EGL_ANDROID_swap_rectangle")) {
1958458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian        if (eglSetSwapRectangleANDROID(display, surface,
1968458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian                0, 0, mWidth, mHeight) == EGL_TRUE) {
1978458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian            // This could fail if this extension is not supported by this
1988458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian            // specific surface (of config)
1998458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian            mFlags |= SWAP_RECTANGLE;
2008458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian        }
201df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    }
2022dd6727c46120f2164f7ac447281f485ece9bc72Mathias Agopian    // when we have the choice between UPDATE_ON_DEMAND and SWAP_RECTANGLE
2032dd6727c46120f2164f7ac447281f485ece9bc72Mathias Agopian    // choose UPDATE_ON_DEMAND, which is more efficient
2042dd6727c46120f2164f7ac447281f485ece9bc72Mathias Agopian    if (mFlags & UPDATE_ON_DEMAND)
2052dd6727c46120f2164f7ac447281f485ece9bc72Mathias Agopian        mFlags &= ~SWAP_RECTANGLE;
2065e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian#endif
2072dd6727c46120f2164f7ac447281f485ece9bc72Mathias Agopian
208df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian
2098458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian    LOGI("flags     : %08x", mFlags);
2108458a3140f51275d6b78b5879f942163c0d618e2Mathias Agopian
211076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mDpiX = mNativeWindow->xdpi;
21280d7a764fc439d7fbd7245ccae6b310386073d9fMathias Agopian    mDpiY = mNativeWindow->ydpi;
2131e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    mRefreshRate = fbDev->fps;
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
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    context = eglCreateContext(display, config, NULL, NULL);
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    /*
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     * Gather OpenGL ES extensions
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     */
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglMakeCurrent(display, surface, surface, context);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const char* const  gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("OpenGL informations:");
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("vendor    : %s", glGetString(GL_VENDOR));
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("renderer  : %s", glGetString(GL_RENDERER));
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("version   : %s", glGetString(GL_VERSION));
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    LOGI("extensions: %s", gl_extensions);
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) {
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFlags |= NPOT_EXTENSION;
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (strstr(gl_extensions, "GL_OES_draw_texture")) {
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFlags |= DRAW_TEXTURE_EXTENSION;
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
254076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    if (strstr( gl_extensions, "GL_OES_EGL_image") &&
255e6bf8b32b616450f80b64d226ea673f4a2e0bf8dMathias Agopian        (strstr(egl_extensions, "EGL_KHR_image_base") ||
256076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian                strstr(egl_extensions, "EGL_KHR_image")) &&
257076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian        strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) {
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        mFlags |= DIRECT_TEXTURE;
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Unbind the context from this thread
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mDisplay = display;
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mConfig  = config;
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mSurface = surface;
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    mContext = context;
268076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mFormat  = fbDev->format;
269076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mPageFlipCount = 0;
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Clean up.  Throw out our local state.
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * (It's entirely possible we'll never get here, since this is meant
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * for real hardware, which doesn't restart.)
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::fini()
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglTerminate(mDisplay);
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    overlay_control_close(mOverlayEngine);
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::releaseScreen() const
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    DisplayHardwareBase::releaseScreen();
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::acquireScreen() const
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    DisplayHardwareBase::acquireScreen();
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t DisplayHardware::getPageFlipCount() const {
297076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mPageFlipCount;
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30074faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopianstatus_t DisplayHardware::compositionComplete() const {
30174faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian    return mNativeWindow->compositionComplete();
30274faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian}
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::flip(const Region& dirty) const
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    checkGLErrors();
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLDisplay dpy = mDisplay;
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLSurface surface = mSurface;
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3115e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian#ifdef EGL_ANDROID_swap_rectangle
312df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    if (mFlags & SWAP_RECTANGLE) {
313b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        const Region newDirty(dirty.intersect(bounds()));
314b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        const Rect b(newDirty.getBounds());
315df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian        eglSetSwapRectangleANDROID(dpy, surface,
316df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian                b.left, b.top, b.width(), b.height());
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
3185e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian#endif
3195e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian
3201e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    if (mFlags & UPDATE_ON_DEMAND) {
32129d06ac9a45e564b4f935b91067fc92c2d4c193dMathias Agopian        mNativeWindow->setUpdateRectangle(dirty.getBounds());
3221e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian    }
3231e16b13857809eaa9bd17fb60ac0a471dc92844bMathias Agopian
324076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mPageFlipCount++;
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglSwapBuffers(dpy, surface);
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    checkEGLErrors("eglSwapBuffers");
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // for debugging
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //glClearColor(1,0,0,0);
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    //glClear(GL_COLOR_BUFFER_BIT);
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t DisplayHardware::getFlags() const
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mFlags;
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid DisplayHardware::makeCurrent() const
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
342