DisplayDevice.cpp revision 00e8c7a88a5b9c4104a71013a713acd3e4d3b77b
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
301a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis#include <gui/SurfaceTextureClient.h>
311a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
33076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <EGL/egl.h>
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <EGL/eglext.h>
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
36076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian#include <hardware/gralloc.h>
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
381b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/FramebufferSurface.h"
391b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian#include "DisplayHardware/HWComposer.h"
401b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
41da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian#include "clz.h"
420f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopian#include "DisplayDevice.h"
431f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian#include "GLExtensions.h"
44c7d14e247117392fbd44aa454622778a25c076aeMathias Agopian#include "SurfaceFlinger.h"
45921e6ac4b7610a178285898d191eb0e3afe906c0Mathias Agopian#include "LayerBase.h"
461f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
47a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian// ----------------------------------------------------------------------------
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectusing namespace android;
49a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian// ----------------------------------------------------------------------------
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic __attribute__((noinline))
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid checkGLErrors()
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
54cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    do {
55cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        // there could be more than one error flag
56cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        GLenum error = glGetError();
57cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian        if (error == GL_NO_ERROR)
58cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian            break;
59e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        ALOGE("GL error 0x%04x", int(error));
60cbb288bfe89f585bf48371bd31b2d4aafa32f32eMathias Agopian    } while(true);
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian// ----------------------------------------------------------------------------
64a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Initialize the display to the specified values.
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
700f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias AgopianDisplayDevice::DisplayDevice(
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const sp<SurfaceFlinger>& flinger,
723ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian        DisplayType type, const wp<IBinder>& displayToken,
731a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        const sp<ANativeWindow>& nativeWindow,
741a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis        const sp<FramebufferSurface>& framebufferSurface,
75a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        EGLConfig config)
7692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    : mFlinger(flinger),
773ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian      mType(type), mHwcDisplayId(-1),
781a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis      mNativeWindow(nativeWindow),
791a4d883dcc1725892bfb5c28dec255a233186524Jamie Gennis      mFramebufferSurface(framebufferSurface),
8092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mDisplay(EGL_NO_DISPLAY),
8192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mSurface(EGL_NO_SURFACE),
8292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mContext(EGL_NO_CONTEXT),
8392a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mDisplayWidth(), mDisplayHeight(), mFormat(),
8492a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mFlags(),
8592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mPageFlipCount(),
8692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mSecureLayerVisible(false),
8792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian      mScreenAcquired(false),
88da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian      mLayerStack(0),
89da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian      mOrientation()
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
91a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    init(config);
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
940f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias AgopianDisplayDevice::~DisplayDevice() {
9592a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    if (mSurface != EGL_NO_SURFACE) {
9692a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        eglDestroySurface(mDisplay, mSurface);
9792a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian        mSurface = EGL_NO_SURFACE;
9892a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    }
9992a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian}
10092a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian
10192a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopianbool DisplayDevice::isValid() const {
10292a979a92c34b7de609ce2b1662c73bb8a2728b9Mathias Agopian    return mFlinger != NULL;
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1050f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianint DisplayDevice::getWidth() const {
106a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mDisplayWidth;
1076163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian}
1086163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian
1090f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianint DisplayDevice::getHeight() const {
110a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mDisplayHeight;
111a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
112a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
1130f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias AgopianPixelFormat DisplayDevice::getFormat() const {
114a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mFormat;
115a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
116a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
1170f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias AgopianEGLSurface DisplayDevice::getEGLSurface() const {
118a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mSurface;
119a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian}
1206163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian
1210f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianvoid DisplayDevice::init(EGLConfig config)
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
123a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    ANativeWindow* const window = mNativeWindow.get();
124a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian
1256163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    int format;
1266163091a2c366f8311fc3ee627dc7deb9681236eMathias Agopian    window->query(window, NATIVE_WINDOW_FORMAT, &format);
127b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian
128a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    /*
129a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian     * Create our display's surface
130b5dd9c0fee3b3d6d35035dfb992951ebea3e0e4eMathias Agopian     */
131385977f6d6c4e76379df384d50695a10cb3757f2Mathias Agopian
1321f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    EGLSurface surface;
133a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    EGLint w, h;
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
135a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    surface = eglCreateWindowSurface(display, config, window, NULL);
1361b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
1371b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1391f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mDisplay = display;
1401f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mSurface = surface;
141a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    mFormat  = format;
1421f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian    mPageFlipCount = 0;
143da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    mViewport.makeInvalid();
144da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    mFrame.makeInvalid();
1451f7bec634f19c123410a5155c8d282e177c01930Mathias Agopian
1465f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian    // external displays are always considered enabled
1473ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    mScreenAcquired = (mType >= DisplayDevice::NUM_DISPLAY_TYPES);
1483ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian
1493ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    // get an h/w composer ID
1503ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopian    mHwcDisplayId = mFlinger->allocateHwcDisplayId(mType);
1515f20e2d4462da3471f59152b32cd8640fa4a21daMathias Agopian
15298a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian    // initialize the display orientation transform.
15300e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
154a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian}
155a350ff98692b3a50cad5cc93f9f83221242ca86aMathias Agopian
1560f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianuint32_t DisplayDevice::getPageFlipCount() const {
157076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    return mPageFlipCount;
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1600f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianstatus_t DisplayDevice::compositionComplete() const {
161a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (mFramebufferSurface == NULL) {
162a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        return NO_ERROR;
163a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
164a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    return mFramebufferSurface->compositionComplete();
16574faca212e2675aa55a30235c77cb6403471a4b9Mathias Agopian}
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1670f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianvoid DisplayDevice::flip(const Region& dirty) const
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    checkGLErrors();
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLDisplay dpy = mDisplay;
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    EGLSurface surface = mSurface;
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1745e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian#ifdef EGL_ANDROID_swap_rectangle
175df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian    if (mFlags & SWAP_RECTANGLE) {
176b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        const Region newDirty(dirty.intersect(bounds()));
177b8a5560e1303cb10f5cd482af466fc04d2bdfcabMathias Agopian        const Rect b(newDirty.getBounds());
178df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian        eglSetSwapRectangleANDROID(dpy, surface,
179df3ca30bf663cb8eed88ee3f16fb5e9a65dc00fcMathias Agopian                b.left, b.top, b.width(), b.height());
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
1815e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian#endif
1825e78e0965169790111f01354e78b0f8d34c94840Mathias Agopian
183076b1cc3a9b90aa5b381a1ed268ca0b548444c9bMathias Agopian    mPageFlipCount++;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1860f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianuint32_t DisplayDevice::getFlags() const
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return mFlags;
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
1910f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianvoid DisplayDevice::dump(String8& res) const
1921d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling{
193a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    if (mFramebufferSurface != NULL) {
194a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian        mFramebufferSurface->dump(res);
195a49126087b4494f4ef50873f3a3f6727265f6621Mathias Agopian    }
1961d21a9cafc534c34a2f28c985c4c7aa176d0e67bErik Gilling}
1971b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
198da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias AgopianEGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy,
199da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        const sp<const DisplayDevice>& hw, EGLContext ctx) {
200da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    EGLBoolean result = EGL_TRUE;
20152bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
2024297734c1156fd8ede7e9c61b1e439f9e1c18cd9Mathias Agopian    if (sur != hw->mSurface) {
203da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        result = eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
204da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        if (result == EGL_TRUE) {
205da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            GLsizei w = hw->mDisplayWidth;
206da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            GLsizei h = hw->mDisplayHeight;
207da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            glViewport(0, 0, w, h);
208da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            glMatrixMode(GL_PROJECTION);
209da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            glLoadIdentity();
210da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            // put the origin in the left-bottom corner
211da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
212da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        }
21352bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian    }
214da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    return result;
21552bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian}
21652bbb1ae239c8a4d05543a23fa8c08467d09c3b2Mathias Agopian
2171b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian// ----------------------------------------------------------------------------
2181b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
2190f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianvoid DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
2203b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    mVisibleLayersSortedByZ = layers;
221ef7b9c7eac036cc1230c64821039d18f8cbd2c1cMathias Agopian    mSecureLayerVisible = false;
2223b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    size_t count = layers.size();
2233b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    for (size_t i=0 ; i<count ; i++) {
2243b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        if (layers[i]->isSecure()) {
2253b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian            mSecureLayerVisible = true;
2263b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian        }
2273b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    }
2283b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian}
2293b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
2303ee454a7bef8bd3d1c9cdd9d17108eb80ebadf2aMathias Agopianconst Vector< sp<LayerBase> >& DisplayDevice::getVisibleLayersSortedByZ() const {
2313b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    return mVisibleLayersSortedByZ;
2323b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian}
2333b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
2340f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianbool DisplayDevice::getSecureLayerVisible() const {
2353b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian    return mSecureLayerVisible;
2363b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian}
2373b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
238cd60f99aba9e750700a967db30b74a29145739cfMathias AgopianRegion DisplayDevice::getDirtyRegion(bool repaintEverything) const {
239cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    Region dirty;
240cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    if (repaintEverything) {
241cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        dirty.set(getBounds());
242cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    } else {
243da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        const Transform& planeTransform(mGlobalTransform);
244cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        dirty = planeTransform.transform(this->dirtyRegion);
245cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian        dirty.andSelf(getBounds());
246cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    }
247cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian    return dirty;
248cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian}
249cd60f99aba9e750700a967db30b74a29145739cfMathias Agopian
2503b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian// ----------------------------------------------------------------------------
251d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
252d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianbool DisplayDevice::canDraw() const {
253d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    return mScreenAcquired;
254d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
255d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
256d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid DisplayDevice::releaseScreen() const {
257d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    mScreenAcquired = false;
258d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
259d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
260d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianvoid DisplayDevice::acquireScreen() const {
261d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    mScreenAcquired = true;
262d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
263d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
264d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopianbool DisplayDevice::isScreenAcquired() const {
265d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian    return mScreenAcquired;
266d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian}
267d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian
268d3ee231eddce0b69ec5e35188dbd0f4a2c3b9ac3Mathias Agopian// ----------------------------------------------------------------------------
2693b1d2b6b2bbfb5df46b1059ec52360974e6f1428Mathias Agopian
27028947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopianvoid DisplayDevice::setLayerStack(uint32_t stack) {
27128947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian    mLayerStack = stack;
27228947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian    dirtyRegion.set(bounds());
27328947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian}
27428947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian
27528947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian// ----------------------------------------------------------------------------
27628947d7fbf9f486539322e8e12dd057568e180c2Mathias Agopian
2770f2f5ff75b7b48ceb64270655ee6b62d09bf4d00Mathias Agopianstatus_t DisplayDevice::orientationToTransfrom(
2781b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        int orientation, int w, int h, Transform* tr)
2791b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian{
2801b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    uint32_t flags = 0;
2811b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    switch (orientation) {
2823165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    case DisplayState::eOrientationDefault:
2831b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        flags = Transform::ROT_0;
2841b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        break;
2853165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    case DisplayState::eOrientation90:
2861b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        flags = Transform::ROT_90;
2871b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        break;
2883165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    case DisplayState::eOrientation180:
2891b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        flags = Transform::ROT_180;
2901b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        break;
2913165cc21cfea781988407b19bd83292b19f05f55Mathias Agopian    case DisplayState::eOrientation270:
2921b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        flags = Transform::ROT_270;
2931b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        break;
2941b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    default:
2951b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian        return BAD_VALUE;
2961b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    }
2971b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    tr->set(flags, w, h);
2981b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    return NO_ERROR;
2991b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian}
3001b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
30100e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopianvoid DisplayDevice::setProjection(int orientation,
30200e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian        const Rect& viewport, const Rect& frame) {
303da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    mOrientation = orientation;
30400e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    mViewport = viewport;
30500e8c7a88a5b9c4104a71013a713acd3e4d3b77bMathias Agopian    mFrame = frame;
306da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    updateGeometryTransform();
307da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian}
308da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
309da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopianvoid DisplayDevice::updateGeometryTransform() {
31098a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian    int w = mDisplayWidth;
31198a121aa916eb7acbf11df0e3e31a6fede6fc9ddMathias Agopian    int h = mDisplayHeight;
312da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    Transform R, S;
313da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian    if (DisplayDevice::orientationToTransfrom(
314da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            mOrientation, w, h, &R) == NO_ERROR) {
315da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        dirtyRegion.set(bounds());
316da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
317da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        Rect viewport(mViewport);
318da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        Rect frame(mFrame);
319da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
320da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        if (!frame.isValid()) {
321da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            // the destination frame can be invalid if it has never been set,
322da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            // in that case we assume the whole display frame.
323da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            frame = Rect(w, h);
324da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        }
325da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
326da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        if (viewport.isEmpty()) {
327da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            // viewport can be invalid if it has never been set, in that case
328da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            // we assume the whole display size.
329da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            // it's also invalid to have an empty viewport, so we handle that
330da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            // case in the same way.
331da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            viewport = Rect(w, h);
332da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            if (R.getOrientation() & Transform::ROT_90) {
333da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                // viewport is always specified in the logical orientation
334da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                // of the display (ie: post-rotation).
335da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian                swap(viewport.right, viewport.bottom);
336da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            }
337da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        }
3381b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian
339da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float src_width  = viewport.width();
340da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float src_height = viewport.height();
341da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float dst_width  = frame.width();
342da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float dst_height = frame.height();
343da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        if (src_width != src_height || dst_width != dst_height) {
344da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            float sx = dst_width  / src_width;
345da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            float sy = dst_height / src_height;
346da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian            S.set(sx, 0, 0, sy);
347da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        }
348da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float src_x = viewport.left;
349da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float src_y = viewport.top;
350da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float dst_x = frame.left;
351da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float dst_y = frame.top;
352da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float tx = dst_x - src_x;
353da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        float ty = dst_y - src_y;
354da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        S.set(tx, ty);
355da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian
356da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        // rotate first, followed by scaling
357da8d0a5c0cf9d41915d3b106cad4aaec3e767c11Mathias Agopian        mGlobalTransform = S * R;
3581b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian    }
3591b03149f3533db04e72e088d3fdd09d0087ca594Mathias Agopian}
360