1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20#include <math.h>
21
22#include <cutils/properties.h>
23
24#include <utils/RefBase.h>
25#include <utils/Log.h>
26
27#include <ui/DisplayInfo.h>
28#include <ui/PixelFormat.h>
29
30#include <gui/Surface.h>
31
32#include <hardware/gralloc.h>
33
34#include "DisplayHardware/DisplaySurface.h"
35#include "DisplayHardware/HWComposer.h"
36#include "RenderEngine/RenderEngine.h"
37
38#include "clz.h"
39#include "DisplayDevice.h"
40#include "SurfaceFlinger.h"
41#include "Layer.h"
42
43// ----------------------------------------------------------------------------
44using namespace android;
45// ----------------------------------------------------------------------------
46
47/*
48 * Initialize the display to the specified values.
49 *
50 */
51
52DisplayDevice::DisplayDevice(
53        const sp<SurfaceFlinger>& flinger,
54        DisplayType type,
55        int32_t hwcId,
56        bool isSecure,
57        const wp<IBinder>& displayToken,
58        const sp<DisplaySurface>& displaySurface,
59        const sp<IGraphicBufferProducer>& producer,
60        EGLConfig config)
61    : mFlinger(flinger),
62      mType(type), mHwcDisplayId(hwcId),
63      mDisplayToken(displayToken),
64      mDisplaySurface(displaySurface),
65      mDisplay(EGL_NO_DISPLAY),
66      mSurface(EGL_NO_SURFACE),
67      mDisplayWidth(), mDisplayHeight(), mFormat(),
68      mFlags(),
69      mPageFlipCount(),
70      mIsSecure(isSecure),
71      mSecureLayerVisible(false),
72      mScreenAcquired(false),
73      mLayerStack(NO_LAYER_STACK),
74      mOrientation()
75{
76    mNativeWindow = new Surface(producer, false);
77    ANativeWindow* const window = mNativeWindow.get();
78
79    int format;
80    window->query(window, NATIVE_WINDOW_FORMAT, &format);
81
82    // Make sure that composition can never be stalled by a virtual display
83    // consumer that isn't processing buffers fast enough. We have to do this
84    // in two places:
85    // * Here, in case the display is composed entirely by HWC.
86    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
87    //   window's swap interval in eglMakeCurrent, so they'll override the
88    //   interval we set here.
89    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
90        window->setSwapInterval(window, 0);
91
92    /*
93     * Create our display's surface
94     */
95
96    EGLSurface surface;
97    EGLint w, h;
98    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
99    surface = eglCreateWindowSurface(display, config, window, NULL);
100    eglQuerySurface(display, surface, EGL_WIDTH,  &mDisplayWidth);
101    eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
102
103    mDisplay = display;
104    mSurface = surface;
105    mFormat  = format;
106    mPageFlipCount = 0;
107    mViewport.makeInvalid();
108    mFrame.makeInvalid();
109
110    // virtual displays are always considered enabled
111    mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);
112
113    // Name the display.  The name will be replaced shortly if the display
114    // was created with createDisplay().
115    switch (mType) {
116        case DISPLAY_PRIMARY:
117            mDisplayName = "Built-in Screen";
118            break;
119        case DISPLAY_EXTERNAL:
120            mDisplayName = "HDMI Screen";
121            break;
122        default:
123            mDisplayName = "Virtual Screen";    // e.g. Overlay #n
124            break;
125    }
126
127    // initialize the display orientation transform.
128    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
129}
130
131DisplayDevice::~DisplayDevice() {
132    if (mSurface != EGL_NO_SURFACE) {
133        eglDestroySurface(mDisplay, mSurface);
134        mSurface = EGL_NO_SURFACE;
135    }
136}
137
138void DisplayDevice::disconnect(HWComposer& hwc) {
139    if (mHwcDisplayId >= 0) {
140        hwc.disconnectDisplay(mHwcDisplayId);
141        if (mHwcDisplayId >= DISPLAY_VIRTUAL)
142            hwc.freeDisplayId(mHwcDisplayId);
143        mHwcDisplayId = -1;
144    }
145}
146
147bool DisplayDevice::isValid() const {
148    return mFlinger != NULL;
149}
150
151int DisplayDevice::getWidth() const {
152    return mDisplayWidth;
153}
154
155int DisplayDevice::getHeight() const {
156    return mDisplayHeight;
157}
158
159PixelFormat DisplayDevice::getFormat() const {
160    return mFormat;
161}
162
163EGLSurface DisplayDevice::getEGLSurface() const {
164    return mSurface;
165}
166
167void DisplayDevice::setDisplayName(const String8& displayName) {
168    if (!displayName.isEmpty()) {
169        // never override the name with an empty name
170        mDisplayName = displayName;
171    }
172}
173
174uint32_t DisplayDevice::getPageFlipCount() const {
175    return mPageFlipCount;
176}
177
178status_t DisplayDevice::compositionComplete() const {
179    return mDisplaySurface->compositionComplete();
180}
181
182void DisplayDevice::flip(const Region& dirty) const
183{
184    mFlinger->getRenderEngine().checkErrors();
185
186    EGLDisplay dpy = mDisplay;
187    EGLSurface surface = mSurface;
188
189#ifdef EGL_ANDROID_swap_rectangle
190    if (mFlags & SWAP_RECTANGLE) {
191        const Region newDirty(dirty.intersect(bounds()));
192        const Rect b(newDirty.getBounds());
193        eglSetSwapRectangleANDROID(dpy, surface,
194                b.left, b.top, b.width(), b.height());
195    }
196#endif
197
198    mPageFlipCount++;
199}
200
201status_t DisplayDevice::beginFrame() const {
202    return mDisplaySurface->beginFrame();
203}
204
205status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
206    DisplaySurface::CompositionType compositionType;
207    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
208    bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
209    if (haveGles && haveHwc) {
210        compositionType = DisplaySurface::COMPOSITION_MIXED;
211    } else if (haveGles) {
212        compositionType = DisplaySurface::COMPOSITION_GLES;
213    } else if (haveHwc) {
214        compositionType = DisplaySurface::COMPOSITION_HWC;
215    } else {
216        // Nothing to do -- when turning the screen off we get a frame like
217        // this. Call it a HWC frame since we won't be doing any GLES work but
218        // will do a prepare/set cycle.
219        compositionType = DisplaySurface::COMPOSITION_HWC;
220    }
221    return mDisplaySurface->prepareFrame(compositionType);
222}
223
224void DisplayDevice::swapBuffers(HWComposer& hwc) const {
225    // We need to call eglSwapBuffers() if:
226    //  (1) we don't have a hardware composer, or
227    //  (2) we did GLES composition this frame, and either
228    //    (a) we have framebuffer target support (not present on legacy
229    //        devices, where HWComposer::commit() handles things); or
230    //    (b) this is a virtual display
231    if (hwc.initCheck() != NO_ERROR ||
232            (hwc.hasGlesComposition(mHwcDisplayId) &&
233             (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
234        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
235        if (!success) {
236            EGLint error = eglGetError();
237            if (error == EGL_CONTEXT_LOST ||
238                    mType == DisplayDevice::DISPLAY_PRIMARY) {
239                LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
240                        mDisplay, mSurface, error);
241            } else {
242                ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
243                        mDisplay, mSurface, error);
244            }
245        }
246    }
247
248    status_t result = mDisplaySurface->advanceFrame();
249    if (result != NO_ERROR) {
250        ALOGE("[%s] failed pushing new frame to HWC: %d",
251                mDisplayName.string(), result);
252    }
253}
254
255void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
256    if (hwc.initCheck() == NO_ERROR) {
257        mDisplaySurface->onFrameCommitted();
258    }
259}
260
261uint32_t DisplayDevice::getFlags() const
262{
263    return mFlags;
264}
265
266EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
267    EGLBoolean result = EGL_TRUE;
268    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
269    if (sur != mSurface) {
270        result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
271        if (result == EGL_TRUE) {
272            if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
273                eglSwapInterval(dpy, 0);
274        }
275    }
276    setViewportAndProjection();
277    return result;
278}
279
280void DisplayDevice::setViewportAndProjection() const {
281    size_t w = mDisplayWidth;
282    size_t h = mDisplayHeight;
283    mFlinger->getRenderEngine().setViewportAndProjection(w, h, w, h, false);
284}
285
286// ----------------------------------------------------------------------------
287
288void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
289    mVisibleLayersSortedByZ = layers;
290    mSecureLayerVisible = false;
291    size_t count = layers.size();
292    for (size_t i=0 ; i<count ; i++) {
293        const sp<Layer>& layer(layers[i]);
294        if (layer->isSecure()) {
295            mSecureLayerVisible = true;
296        }
297    }
298}
299
300const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
301    return mVisibleLayersSortedByZ;
302}
303
304bool DisplayDevice::getSecureLayerVisible() const {
305    return mSecureLayerVisible;
306}
307
308Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
309    Region dirty;
310    if (repaintEverything) {
311        dirty.set(getBounds());
312    } else {
313        const Transform& planeTransform(mGlobalTransform);
314        dirty = planeTransform.transform(this->dirtyRegion);
315        dirty.andSelf(getBounds());
316    }
317    return dirty;
318}
319
320// ----------------------------------------------------------------------------
321
322bool DisplayDevice::canDraw() const {
323    return mScreenAcquired;
324}
325
326void DisplayDevice::releaseScreen() const {
327    mScreenAcquired = false;
328}
329
330void DisplayDevice::acquireScreen() const {
331    mScreenAcquired = true;
332}
333
334bool DisplayDevice::isScreenAcquired() const {
335    return mScreenAcquired;
336}
337
338// ----------------------------------------------------------------------------
339
340void DisplayDevice::setLayerStack(uint32_t stack) {
341    mLayerStack = stack;
342    dirtyRegion.set(bounds());
343}
344
345// ----------------------------------------------------------------------------
346
347uint32_t DisplayDevice::getOrientationTransform() const {
348    uint32_t transform = 0;
349    switch (mOrientation) {
350        case DisplayState::eOrientationDefault:
351            transform = Transform::ROT_0;
352            break;
353        case DisplayState::eOrientation90:
354            transform = Transform::ROT_90;
355            break;
356        case DisplayState::eOrientation180:
357            transform = Transform::ROT_180;
358            break;
359        case DisplayState::eOrientation270:
360            transform = Transform::ROT_270;
361            break;
362    }
363    return transform;
364}
365
366status_t DisplayDevice::orientationToTransfrom(
367        int orientation, int w, int h, Transform* tr)
368{
369    uint32_t flags = 0;
370    switch (orientation) {
371    case DisplayState::eOrientationDefault:
372        flags = Transform::ROT_0;
373        break;
374    case DisplayState::eOrientation90:
375        flags = Transform::ROT_90;
376        break;
377    case DisplayState::eOrientation180:
378        flags = Transform::ROT_180;
379        break;
380    case DisplayState::eOrientation270:
381        flags = Transform::ROT_270;
382        break;
383    default:
384        return BAD_VALUE;
385    }
386    tr->set(flags, w, h);
387    return NO_ERROR;
388}
389
390void DisplayDevice::setProjection(int orientation,
391        const Rect& newViewport, const Rect& newFrame) {
392    Rect viewport(newViewport);
393    Rect frame(newFrame);
394
395    const int w = mDisplayWidth;
396    const int h = mDisplayHeight;
397
398    Transform R;
399    DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
400
401    if (!frame.isValid()) {
402        // the destination frame can be invalid if it has never been set,
403        // in that case we assume the whole display frame.
404        frame = Rect(w, h);
405    }
406
407    if (viewport.isEmpty()) {
408        // viewport can be invalid if it has never been set, in that case
409        // we assume the whole display size.
410        // it's also invalid to have an empty viewport, so we handle that
411        // case in the same way.
412        viewport = Rect(w, h);
413        if (R.getOrientation() & Transform::ROT_90) {
414            // viewport is always specified in the logical orientation
415            // of the display (ie: post-rotation).
416            swap(viewport.right, viewport.bottom);
417        }
418    }
419
420    dirtyRegion.set(getBounds());
421
422    Transform TL, TP, S;
423    float src_width  = viewport.width();
424    float src_height = viewport.height();
425    float dst_width  = frame.width();
426    float dst_height = frame.height();
427    if (src_width != dst_width || src_height != dst_height) {
428        float sx = dst_width  / src_width;
429        float sy = dst_height / src_height;
430        S.set(sx, 0, 0, sy);
431    }
432
433    float src_x = viewport.left;
434    float src_y = viewport.top;
435    float dst_x = frame.left;
436    float dst_y = frame.top;
437    TL.set(-src_x, -src_y);
438    TP.set(dst_x, dst_y);
439
440    // The viewport and frame are both in the logical orientation.
441    // Apply the logical translation, scale to physical size, apply the
442    // physical translation and finally rotate to the physical orientation.
443    mGlobalTransform = R * TP * S * TL;
444
445    const uint8_t type = mGlobalTransform.getType();
446    mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
447            (type >= Transform::SCALE));
448
449    mScissor = mGlobalTransform.transform(viewport);
450    if (mScissor.isEmpty()) {
451        mScissor = getBounds();
452    }
453
454    mOrientation = orientation;
455    mViewport = viewport;
456    mFrame = frame;
457}
458
459void DisplayDevice::dump(String8& result) const {
460    const Transform& tr(mGlobalTransform);
461    result.appendFormat(
462        "+ DisplayDevice: %s\n"
463        "   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
464        "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%u\n"
465        "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
466        "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
467        mDisplayName.string(), mType, mHwcDisplayId,
468        mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
469        mOrientation, tr.getType(), getPageFlipCount(),
470        mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
471        mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
472        mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
473        mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
474        tr[0][0], tr[1][0], tr[2][0],
475        tr[0][1], tr[1][1], tr[2][1],
476        tr[0][2], tr[1][2], tr[2][2]);
477
478    String8 surfaceDump;
479    mDisplaySurface->dump(surfaceDump);
480    result.append(surfaceDump);
481}
482