DisplayDevice.cpp revision 89fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919e
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
27c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian#include <ui/DisplayInfo.h>
28076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <ui/PixelFormat.h>
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30e3c697fb929c856b59fa56a8e05a2a7eba187c3dMathias Agopian#include <gui/Surface.h>
311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
32076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/gralloc.h>
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
3499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall#include "DisplayHardware/DisplaySurface.h"
351b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
36875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian#include "RenderEngine/RenderEngine.h"
371b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
38da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian#include "clz.h"
390f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
40c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian#include "SurfaceFlinger.h"
4113127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian#include "Layer.h"
421f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
43a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian// ----------------------------------------------------------------------------
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android;
45a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian// ----------------------------------------------------------------------------
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
4789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe#ifdef EGL_ANDROID_swap_rectangle
4889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatic constexpr bool kEGLAndroidSwapRectangle = true;
4989fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe#else
5089fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampestatic constexpr bool kEGLAndroidSwapRectangle = false;
5189fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe#endif
5289fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe
5389fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe#if !defined(EGL_EGLEXT_PROTOTYPES) || !defined(EGL_ANDROID_swap_rectangle)
5489fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe// Dummy implementation in case it is missing.
5589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampeinline void eglSetSwapRectangleANDROID (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) {
5689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe}
5789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe#endif
5889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Initialize the display to the specified values.
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
640f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias AgopianDisplayDevice::DisplayDevice(
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<SurfaceFlinger>& flinger,
66dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        DisplayType type,
67ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        int32_t hwcId,
6819e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall        int format,
69dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        bool isSecure,
70dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis        const wp<IBinder>& displayToken,
7199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall        const sp<DisplaySurface>& displaySurface,
72db89edc94bd2a78226b407f9f7261e202e7fa325Mathias Agopian        const sp<IGraphicBufferProducer>& producer,
73a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig config)
74b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall    : lastCompositionHadVisibleLayers(false),
75b7a0549c983bef103ce07eb3af5905febc6e538eJesse Hall      mFlinger(flinger),
76ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall      mType(type), mHwcDisplayId(hwcId),
7727e2562868dcd3ad26f9b4677b64ae272941704eChih-Wei Huang      mDisplayToken(displayToken),
7899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall      mDisplaySurface(displaySurface),
7992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mDisplay(EGL_NO_DISPLAY),
8092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mSurface(EGL_NO_SURFACE),
8192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mDisplayWidth(), mDisplayHeight(), mFormat(),
8292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mFlags(),
8392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mPageFlipCount(),
84dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis      mIsSecure(isSecure),
8592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mSecureLayerVisible(false),
8601e29054e672301e4adbbca15b3562a59a20f267Jesse Hall      mLayerStack(NO_LAYER_STACK),
872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani      mOrientation(),
886c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine      mPowerMode(HWC_POWER_MODE_OFF),
896c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine      mActiveConfig(0)
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
9183cafffeac037ab2f9d00f98f8d2f3da8fc9b857Jesse Hall    mNativeWindow = new Surface(producer, false);
92a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ANativeWindow* const window = mNativeWindow.get();
93a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
94a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    /*
95a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian     * Create our display's surface
96b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian     */
97385977f6d6c4e76379df384d50695a10cb3757f2Mathias Agopian
981f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    EGLSurface surface;
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
10019e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall    if (config == EGL_NO_CONFIG) {
10119e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall        config = RenderEngine::chooseEglConfig(display, format);
10219e872912af66c53a4350afcc333bbafaf6a2294Jesse Hall    }
103a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    surface = eglCreateWindowSurface(display, config, window, NULL);
1041b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
1051b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1074ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong    // Make sure that composition can never be stalled by a virtual display
1084ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong    // consumer that isn't processing buffers fast enough. We have to do this
1094ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong    // in two places:
1104ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong    // * Here, in case the display is composed entirely by HWC.
1114ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
1124ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong    //   window's swap interval in eglMakeCurrent, so they'll override the
1134ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong    //   interval we set here.
1144ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
1154ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong        window->setSwapInterval(window, 0);
1164ee5696dfbcea1078b24e7c089de74e7cf4e55caJohn Dong
11747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    mConfig = config;
1181f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mDisplay = display;
1191f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mSurface = surface;
120a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mFormat  = format;
1211f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mPageFlipCount = 0;
122da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    mViewport.makeInvalid();
123da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    mFrame.makeInvalid();
1241f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
125ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    // virtual displays are always considered enabled
1262c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
1272c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
1285f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
1298dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    // Name the display.  The name will be replaced shortly if the display
1308dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    // was created with createDisplay().
1318dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    switch (mType) {
1328dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden        case DISPLAY_PRIMARY:
1338dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden            mDisplayName = "Built-in Screen";
1348dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden            break;
1358dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden        case DISPLAY_EXTERNAL:
1368dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden            mDisplayName = "HDMI Screen";
1378dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden            break;
1388dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden        default:
1398dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden            mDisplayName = "Virtual Screen";    // e.g. Overlay #n
1408dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden            break;
1418dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    }
1428dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden
14398a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian    // initialize the display orientation transform.
14400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
145a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
146a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
147ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse HallDisplayDevice::~DisplayDevice() {
148ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    if (mSurface != EGL_NO_SURFACE) {
149ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        eglDestroySurface(mDisplay, mSurface);
150ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall        mSurface = EGL_NO_SURFACE;
151ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    }
152ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall}
153ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall
15402d86567d95b99e1142941ed7ec23a4465822813Jesse Hallvoid DisplayDevice::disconnect(HWComposer& hwc) {
15502d86567d95b99e1142941ed7ec23a4465822813Jesse Hall    if (mHwcDisplayId >= 0) {
15602d86567d95b99e1142941ed7ec23a4465822813Jesse Hall        hwc.disconnectDisplay(mHwcDisplayId);
15702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall        if (mHwcDisplayId >= DISPLAY_VIRTUAL)
15802d86567d95b99e1142941ed7ec23a4465822813Jesse Hall            hwc.freeDisplayId(mHwcDisplayId);
15902d86567d95b99e1142941ed7ec23a4465822813Jesse Hall        mHwcDisplayId = -1;
16002d86567d95b99e1142941ed7ec23a4465822813Jesse Hall    }
16102d86567d95b99e1142941ed7ec23a4465822813Jesse Hall}
16202d86567d95b99e1142941ed7ec23a4465822813Jesse Hall
163ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hallbool DisplayDevice::isValid() const {
164ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    return mFlinger != NULL;
165ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall}
166ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall
167ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hallint DisplayDevice::getWidth() const {
168ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    return mDisplayWidth;
169ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall}
170ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall
171ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hallint DisplayDevice::getHeight() const {
172ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    return mDisplayHeight;
173ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall}
174ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall
175ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse HallPixelFormat DisplayDevice::getFormat() const {
176ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    return mFormat;
177ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall}
178ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall
179ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse HallEGLSurface DisplayDevice::getEGLSurface() const {
180ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall    return mSurface;
181ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall}
182ffe1f19ca9707f84cb9fdb06209bf36cd8c2ef0aJesse Hall
1839e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopianvoid DisplayDevice::setDisplayName(const String8& displayName) {
1849e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian    if (!displayName.isEmpty()) {
1859e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        // never override the name with an empty name
1869e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian        mDisplayName = displayName;
1879e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian    }
1889e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian}
1899e2463e71796964cfaa06bf09a880875ac3537bcMathias Agopian
1900f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianuint32_t DisplayDevice::getPageFlipCount() const {
191076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mPageFlipCount;
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1940f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianstatus_t DisplayDevice::compositionComplete() const {
19599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    return mDisplaySurface->compositionComplete();
19674faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian}
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1980f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianvoid DisplayDevice::flip(const Region& dirty) const
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
200875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    mFlinger->getRenderEngine().checkErrors();
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20289fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe    if (kEGLAndroidSwapRectangle) {
20389fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe        if (mFlags & SWAP_RECTANGLE) {
20489fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe            const Region newDirty(dirty.intersect(bounds()));
20589fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe            const Rect b(newDirty.getBounds());
20689fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe            eglSetSwapRectangleANDROID(mDisplay, mSurface,
20789fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe                    b.left, b.top, b.width(), b.height());
20889fd4f7fa6bd17ce5400979c3b9e5ba0bf7e919eAndreas Gampe        }
20901e29054e672301e4adbbca15b3562a59a20f267Jesse Hall    }
210d870703d5566490cfdfb389d9336b2b8d3c6cc7aMathias Agopian
211076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mPageFlipCount++;
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
2147143316af216fa92c31a60d4407b707637382da1Dan Stozastatus_t DisplayDevice::beginFrame(bool mustRecompose) const {
2157143316af216fa92c31a60d4407b707637382da1Dan Stoza    return mDisplaySurface->beginFrame(mustRecompose);
216028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall}
217028dc8f2d72bc7cd4fbe7808781443125a742f78Jesse Hall
21838efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hallstatus_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
21938efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    DisplaySurface::CompositionType compositionType;
22038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
22138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
22238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    if (haveGles && haveHwc) {
22338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        compositionType = DisplaySurface::COMPOSITION_MIXED;
22438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    } else if (haveGles) {
22538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        compositionType = DisplaySurface::COMPOSITION_GLES;
22638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    } else if (haveHwc) {
22738efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        compositionType = DisplaySurface::COMPOSITION_HWC;
22838efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    } else {
22938efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        // Nothing to do -- when turning the screen off we get a frame like
23038efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        // this. Call it a HWC frame since we won't be doing any GLES work but
23138efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        // will do a prepare/set cycle.
23238efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall        compositionType = DisplaySurface::COMPOSITION_HWC;
23338efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    }
23438efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall    return mDisplaySurface->prepareFrame(compositionType);
23538efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall}
23638efe86d9459cf5c96a24a34cc5cbf31fdba7e19Jesse Hall
237da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianvoid DisplayDevice::swapBuffers(HWComposer& hwc) const {
23822a99f0fc2884227b9d7e46959fcbe6270667efbAndy McFadden    // We need to call eglSwapBuffers() if:
23922a99f0fc2884227b9d7e46959fcbe6270667efbAndy McFadden    //  (1) we don't have a hardware composer, or
24022a99f0fc2884227b9d7e46959fcbe6270667efbAndy McFadden    //  (2) we did GLES composition this frame, and either
24122a99f0fc2884227b9d7e46959fcbe6270667efbAndy McFadden    //    (a) we have framebuffer target support (not present on legacy
24222a99f0fc2884227b9d7e46959fcbe6270667efbAndy McFadden    //        devices, where HWComposer::commit() handles things); or
24322a99f0fc2884227b9d7e46959fcbe6270667efbAndy McFadden    //    (b) this is a virtual display
24499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    if (hwc.initCheck() != NO_ERROR ||
24599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall            (hwc.hasGlesComposition(mHwcDisplayId) &&
24622a99f0fc2884227b9d7e46959fcbe6270667efbAndy McFadden             (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
24799c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
24899c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall        if (!success) {
24999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall            EGLint error = eglGetError();
25099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall            if (error == EGL_CONTEXT_LOST ||
25199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                    mType == DisplayDevice::DISPLAY_PRIMARY) {
25299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
25399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        mDisplay, mSurface, error);
25499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall            } else {
25599c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
25699c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                        mDisplay, mSurface, error);
257da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian            }
258da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian        }
259da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
26052e21483fa48baeb4a88372d75e083bca2e92923Mathias Agopian
26199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    status_t result = mDisplaySurface->advanceFrame();
26299c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    if (result != NO_ERROR) {
26399c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall        ALOGE("[%s] failed pushing new frame to HWC: %d",
26499c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall                mDisplayName.string(), result);
26532341381c9493d7953e40f7f79653cfc52868863Mathias Agopian    }
266da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
267da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
268da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopianvoid DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
269da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    if (hwc.initCheck() == NO_ERROR) {
270851cfe834295224cd64bdd499872b95b19c4de8cJesse Hall        mDisplaySurface->onFrameCommitted();
271da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian    }
272da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian}
273da27af9832a0170f1fc40ef3f21371c4d30d21b3Mathias Agopian
2740f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianuint32_t DisplayDevice::getFlags() const
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mFlags;
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
279875d8e1323536e16dcfc90c9674d7ad32116a69aMathias AgopianEGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
280da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    EGLBoolean result = EGL_TRUE;
28152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
282875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    if (sur != mSurface) {
283875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian        result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
284da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        if (result == EGL_TRUE) {
285f460f55c84b0a75de749b8a784059f5ff423ed93Jesse Hall            if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
286f460f55c84b0a75de749b8a784059f5ff423ed93Jesse Hall                eglSwapInterval(dpy, 0);
287da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        }
28852bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
289931bda1c472ba8c8e965bdba6757ff94154df903Mathias Agopian    setViewportAndProjection();
290da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    return result;
29152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian}
29252bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
293875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopianvoid DisplayDevice::setViewportAndProjection() const {
294875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    size_t w = mDisplayWidth;
295875d8e1323536e16dcfc90c9674d7ad32116a69aMathias Agopian    size_t h = mDisplayHeight;
296c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza    Rect sourceCrop(0, 0, w, h);
297c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews    mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h,
298c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews        false, Transform::ROT_0);
299bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian}
300bae92d0d605e99a14731add4f11b72413b2835e5Mathias Agopian
3011b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian// ----------------------------------------------------------------------------
3021b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
30313127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianvoid DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
3043b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleLayersSortedByZ = layers;
305ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian    mSecureLayerVisible = false;
3063b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    size_t count = layers.size();
3073b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
30813127d8921356dff794250e04208c3ed60b3a3dfMathias Agopian        const sp<Layer>& layer(layers[i]);
309f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        if (layer->isSecure()) {
3103b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            mSecureLayerVisible = true;
3113b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
3123b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
3133b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian}
3143b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
31513127d8921356dff794250e04208c3ed60b3a3dfMathias Agopianconst Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
3163b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    return mVisibleLayersSortedByZ;
3173b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian}
3183b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
3190f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianbool DisplayDevice::getSecureLayerVisible() const {
3203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    return mSecureLayerVisible;
3213b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian}
3223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
323cd60f99aba9e750700a967db30b74a29145739cfMathias AgopianRegion DisplayDevice::getDirtyRegion(bool repaintEverything) const {
324cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    Region dirty;
325cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (repaintEverything) {
326cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        dirty.set(getBounds());
327cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    } else {
328da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        const Transform& planeTransform(mGlobalTransform);
329cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        dirty = planeTransform.transform(this->dirtyRegion);
330cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        dirty.andSelf(getBounds());
331cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
332cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    return dirty;
333cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
334cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
3353b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian// ----------------------------------------------------------------------------
3362c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanivoid DisplayDevice::setPowerMode(int mode) {
3372c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    mPowerMode = mode;
338d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
339d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
3402c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malaniint DisplayDevice::getPowerMode()  const {
3412c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    return mPowerMode;
342d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
343d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
3442c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malanibool DisplayDevice::isDisplayOn() const {
3452c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    return (mPowerMode != HWC_POWER_MODE_OFF);
346d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
347d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
348d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian// ----------------------------------------------------------------------------
3496c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentinevoid DisplayDevice::setActiveConfig(int mode) {
3506c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    mActiveConfig = mode;
3516c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
3526c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
3536c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentineint DisplayDevice::getActiveConfig()  const {
3546c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine    return mActiveConfig;
3556c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine}
3566c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine
3576c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine// ----------------------------------------------------------------------------
3583b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
35928947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopianvoid DisplayDevice::setLayerStack(uint32_t stack) {
36028947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian    mLayerStack = stack;
36128947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian    dirtyRegion.set(bounds());
36228947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian}
36328947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian
36428947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian// ----------------------------------------------------------------------------
36528947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian
366c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopianuint32_t DisplayDevice::getOrientationTransform() const {
367c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    uint32_t transform = 0;
368c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    switch (mOrientation) {
369c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        case DisplayState::eOrientationDefault:
370c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            transform = Transform::ROT_0;
371c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            break;
372c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        case DisplayState::eOrientation90:
373c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            transform = Transform::ROT_90;
374c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            break;
375c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        case DisplayState::eOrientation180:
376c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            transform = Transform::ROT_180;
377c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            break;
378c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian        case DisplayState::eOrientation270:
379c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            transform = Transform::ROT_270;
380c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian            break;
381c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    }
382c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian    return transform;
383c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian}
384c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian
3850f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianstatus_t DisplayDevice::orientationToTransfrom(
3861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        int orientation, int w, int h, Transform* tr)
3871b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian{
3881b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    uint32_t flags = 0;
3891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    switch (orientation) {
3903165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    case DisplayState::eOrientationDefault:
3911b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        flags = Transform::ROT_0;
3921b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        break;
3933165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    case DisplayState::eOrientation90:
3941b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        flags = Transform::ROT_90;
3951b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        break;
3963165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    case DisplayState::eOrientation180:
3971b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        flags = Transform::ROT_180;
3981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        break;
3993165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    case DisplayState::eOrientation270:
4001b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        flags = Transform::ROT_270;
4011b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        break;
4021b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    default:
4031b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        return BAD_VALUE;
4041b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    }
4051b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    tr->set(flags, w, h);
4061b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    return NO_ERROR;
4071b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian}
4081b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
40947e45405d1533aa73307014f7bf371e118695cf3Michael Lentinevoid DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
41047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    dirtyRegion.set(getBounds());
41147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine
412f2568dea419562ad75b2e79dcbd358af34e9f8adMichael Lentine    if (mSurface != EGL_NO_SURFACE) {
413f2568dea419562ad75b2e79dcbd358af34e9f8adMichael Lentine        eglDestroySurface(mDisplay, mSurface);
414f2568dea419562ad75b2e79dcbd358af34e9f8adMichael Lentine        mSurface = EGL_NO_SURFACE;
415f2568dea419562ad75b2e79dcbd358af34e9f8adMichael Lentine    }
416f2568dea419562ad75b2e79dcbd358af34e9f8adMichael Lentine
41747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    mDisplaySurface->resizeBuffers(newWidth, newHeight);
41847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine
41947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    ANativeWindow* const window = mNativeWindow.get();
42047e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    mSurface = eglCreateWindowSurface(mDisplay, mConfig, window, NULL);
42147e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    eglQuerySurface(mDisplay, mSurface, EGL_WIDTH,  &mDisplayWidth);
42247e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    eglQuerySurface(mDisplay, mSurface, EGL_HEIGHT, &mDisplayHeight);
42347e45405d1533aa73307014f7bf371e118695cf3Michael Lentine
42447e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    LOG_FATAL_IF(mDisplayWidth != newWidth,
42547e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                "Unable to set new width to %d", newWidth);
42647e45405d1533aa73307014f7bf371e118695cf3Michael Lentine    LOG_FATAL_IF(mDisplayHeight != newHeight,
42747e45405d1533aa73307014f7bf371e118695cf3Michael Lentine                "Unable to set new height to %d", newHeight);
42847e45405d1533aa73307014f7bf371e118695cf3Michael Lentine}
42947e45405d1533aa73307014f7bf371e118695cf3Michael Lentine
43000e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopianvoid DisplayDevice::setProjection(int orientation,
431f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        const Rect& newViewport, const Rect& newFrame) {
432f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    Rect viewport(newViewport);
433f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    Rect frame(newFrame);
434da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
435f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    const int w = mDisplayWidth;
436f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    const int h = mDisplayHeight;
437da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
438f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    Transform R;
439f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
4401b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
441f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    if (!frame.isValid()) {
442f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        // the destination frame can be invalid if it has never been set,
443f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        // in that case we assume the whole display frame.
444f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        frame = Rect(w, h);
445f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    }
4466360ec42d414b1351ecb6c5fc4b8afa30d8f4ebfJesse Hall
447f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    if (viewport.isEmpty()) {
448f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        // viewport can be invalid if it has never been set, in that case
449f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        // we assume the whole display size.
450f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        // it's also invalid to have an empty viewport, so we handle that
451f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        // case in the same way.
452f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        viewport = Rect(w, h);
453f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        if (R.getOrientation() & Transform::ROT_90) {
454f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian            // viewport is always specified in the logical orientation
455f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian            // of the display (ie: post-rotation).
456f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian            swap(viewport.right, viewport.bottom);
457766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        }
4581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    }
459f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian
460f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    dirtyRegion.set(getBounds());
461f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian
462f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    Transform TL, TP, S;
463f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    float src_width  = viewport.width();
464f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    float src_height = viewport.height();
465f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    float dst_width  = frame.width();
466f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    float dst_height = frame.height();
467f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    if (src_width != dst_width || src_height != dst_height) {
468f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        float sx = dst_width  / src_width;
469f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        float sy = dst_height / src_height;
470f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian        S.set(sx, 0, 0, sy);
471f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    }
472f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian
473f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    float src_x = viewport.left;
474f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    float src_y = viewport.top;
475f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    float dst_x = frame.left;
476f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    float dst_y = frame.top;
477f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    TL.set(-src_x, -src_y);
478f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    TP.set(dst_x, dst_y);
479f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian
480f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    // The viewport and frame are both in the logical orientation.
481f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    // Apply the logical translation, scale to physical size, apply the
482f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    // physical translation and finally rotate to the physical orientation.
483f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    mGlobalTransform = R * TP * S * TL;
484f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian
485f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    const uint8_t type = mGlobalTransform.getType();
486f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
487f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian            (type >= Transform::SCALE));
488f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian
489f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    mScissor = mGlobalTransform.transform(viewport);
490f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    if (mScissor.isEmpty()) {
4916c7f25afb75ac155bad0b3bc17c0089d0337d060Mathias Agopian        mScissor = getBounds();
492f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    }
493f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian
494f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    mOrientation = orientation;
495f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    mViewport = viewport;
496f5f714aa188884098aaecbe39d0bc61b40311c0dMathias Agopian    mFrame = frame;
4971b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian}
4981d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian
49974d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopianvoid DisplayDevice::dump(String8& result) const {
5001d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian    const Transform& tr(mGlobalTransform);
50174d211ae26a0257c6075a823812e40b55aa1e653Mathias Agopian    result.appendFormat(
5021d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        "+ DisplayDevice: %s\n"
50302d86567d95b99e1142941ed7ec23a4465822813Jesse Hall        "   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
5046c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n"
505766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
5061d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
50702d86567d95b99e1142941ed7ec23a4465822813Jesse Hall        mDisplayName.string(), mType, mHwcDisplayId,
5081d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
5091d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        mOrientation, tr.getType(), getPageFlipCount(),
5106c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        mIsSecure, mSecureLayerVisible, mPowerMode, mActiveConfig,
5116c9e34a98a63033b80bd1c24c7aa1304f912f10aMichael Lentine        mVisibleLayersSortedByZ.size(),
5121d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
5131d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
514766dc49c17dda977bf7b93a5fd8da41c0b737611Mathias Agopian        mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
5151d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        tr[0][0], tr[1][0], tr[2][0],
5161d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        tr[0][1], tr[1][1], tr[2][1],
5171d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian        tr[0][2], tr[1][2], tr[2][2]);
5181d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian
51999c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    String8 surfaceDump;
52099c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    mDisplaySurface->dump(surfaceDump);
52199c7dbb24994df2f3e175f7b25dd2c9dd92a72f0Jesse Hall    result.append(surfaceDump);
5221d12d8a8e61163b35cf42c51c558a67138014e82Mathias Agopian}
523