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