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