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