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