DisplayDevice.cpp revision 2c9b11f0291210c9b9513a1a0cce6afebd361b3b
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{
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    mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
113                  HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
114
115    // Name the display.  The name will be replaced shortly if the display
116    // was created with createDisplay().
117    switch (mType) {
118        case DISPLAY_PRIMARY:
119            mDisplayName = "Built-in Screen";
120            break;
121        case DISPLAY_EXTERNAL:
122            mDisplayName = "HDMI Screen";
123            break;
124        default:
125            mDisplayName = "Virtual Screen";    // e.g. Overlay #n
126            break;
127    }
128
129    // initialize the display orientation transform.
130    setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
131}
132
133DisplayDevice::~DisplayDevice() {
134    if (mSurface != EGL_NO_SURFACE) {
135        eglDestroySurface(mDisplay, mSurface);
136        mSurface = EGL_NO_SURFACE;
137    }
138}
139
140void DisplayDevice::disconnect(HWComposer& hwc) {
141    if (mHwcDisplayId >= 0) {
142        hwc.disconnectDisplay(mHwcDisplayId);
143        if (mHwcDisplayId >= DISPLAY_VIRTUAL)
144            hwc.freeDisplayId(mHwcDisplayId);
145        mHwcDisplayId = -1;
146    }
147}
148
149bool DisplayDevice::isValid() const {
150    return mFlinger != NULL;
151}
152
153int DisplayDevice::getWidth() const {
154    return mDisplayWidth;
155}
156
157int DisplayDevice::getHeight() const {
158    return mDisplayHeight;
159}
160
161PixelFormat DisplayDevice::getFormat() const {
162    return mFormat;
163}
164
165EGLSurface DisplayDevice::getEGLSurface() const {
166    return mSurface;
167}
168
169void DisplayDevice::setDisplayName(const String8& displayName) {
170    if (!displayName.isEmpty()) {
171        // never override the name with an empty name
172        mDisplayName = displayName;
173    }
174}
175
176uint32_t DisplayDevice::getPageFlipCount() const {
177    return mPageFlipCount;
178}
179
180status_t DisplayDevice::compositionComplete() const {
181    return mDisplaySurface->compositionComplete();
182}
183
184void DisplayDevice::flip(const Region& dirty) const
185{
186    mFlinger->getRenderEngine().checkErrors();
187
188    EGLDisplay dpy = mDisplay;
189    EGLSurface surface = mSurface;
190
191#ifdef EGL_ANDROID_swap_rectangle
192    if (mFlags & SWAP_RECTANGLE) {
193        const Region newDirty(dirty.intersect(bounds()));
194        const Rect b(newDirty.getBounds());
195        eglSetSwapRectangleANDROID(dpy, surface,
196                b.left, b.top, b.width(), b.height());
197    }
198#else
199    (void) dirty; // Eliminate unused parameter warning
200#endif
201
202    mPageFlipCount++;
203}
204
205status_t DisplayDevice::beginFrame(bool mustRecompose) const {
206    return mDisplaySurface->beginFrame(mustRecompose);
207}
208
209status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
210    DisplaySurface::CompositionType compositionType;
211    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
212    bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
213    if (haveGles && haveHwc) {
214        compositionType = DisplaySurface::COMPOSITION_MIXED;
215    } else if (haveGles) {
216        compositionType = DisplaySurface::COMPOSITION_GLES;
217    } else if (haveHwc) {
218        compositionType = DisplaySurface::COMPOSITION_HWC;
219    } else {
220        // Nothing to do -- when turning the screen off we get a frame like
221        // this. Call it a HWC frame since we won't be doing any GLES work but
222        // will do a prepare/set cycle.
223        compositionType = DisplaySurface::COMPOSITION_HWC;
224    }
225    return mDisplaySurface->prepareFrame(compositionType);
226}
227
228void DisplayDevice::swapBuffers(HWComposer& hwc) const {
229    // We need to call eglSwapBuffers() if:
230    //  (1) we don't have a hardware composer, or
231    //  (2) we did GLES composition this frame, and either
232    //    (a) we have framebuffer target support (not present on legacy
233    //        devices, where HWComposer::commit() handles things); or
234    //    (b) this is a virtual display
235    if (hwc.initCheck() != NO_ERROR ||
236            (hwc.hasGlesComposition(mHwcDisplayId) &&
237             (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
238        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
239        if (!success) {
240            EGLint error = eglGetError();
241            if (error == EGL_CONTEXT_LOST ||
242                    mType == DisplayDevice::DISPLAY_PRIMARY) {
243                LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
244                        mDisplay, mSurface, error);
245            } else {
246                ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
247                        mDisplay, mSurface, error);
248            }
249        }
250    }
251
252    status_t result = mDisplaySurface->advanceFrame();
253    if (result != NO_ERROR) {
254        ALOGE("[%s] failed pushing new frame to HWC: %d",
255                mDisplayName.string(), result);
256    }
257}
258
259void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
260    if (hwc.initCheck() == NO_ERROR) {
261        mDisplaySurface->onFrameCommitted();
262    }
263}
264
265uint32_t DisplayDevice::getFlags() const
266{
267    return mFlags;
268}
269
270EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
271    EGLBoolean result = EGL_TRUE;
272    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
273    if (sur != mSurface) {
274        result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
275        if (result == EGL_TRUE) {
276            if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
277                eglSwapInterval(dpy, 0);
278        }
279    }
280    setViewportAndProjection();
281    return result;
282}
283
284void DisplayDevice::setViewportAndProjection() const {
285    size_t w = mDisplayWidth;
286    size_t h = mDisplayHeight;
287    Rect sourceCrop(0, 0, w, h);
288    mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, false);
289}
290
291// ----------------------------------------------------------------------------
292
293void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
294    mVisibleLayersSortedByZ = layers;
295    mSecureLayerVisible = false;
296    size_t count = layers.size();
297    for (size_t i=0 ; i<count ; i++) {
298        const sp<Layer>& layer(layers[i]);
299        if (layer->isSecure()) {
300            mSecureLayerVisible = true;
301        }
302    }
303}
304
305const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
306    return mVisibleLayersSortedByZ;
307}
308
309bool DisplayDevice::getSecureLayerVisible() const {
310    return mSecureLayerVisible;
311}
312
313Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
314    Region dirty;
315    if (repaintEverything) {
316        dirty.set(getBounds());
317    } else {
318        const Transform& planeTransform(mGlobalTransform);
319        dirty = planeTransform.transform(this->dirtyRegion);
320        dirty.andSelf(getBounds());
321    }
322    return dirty;
323}
324
325// ----------------------------------------------------------------------------
326void DisplayDevice::setPowerMode(int mode) {
327    mPowerMode = mode;
328}
329
330int DisplayDevice::getPowerMode()  const {
331    return mPowerMode;
332}
333
334bool DisplayDevice::isDisplayOn() const {
335    return (mPowerMode != HWC_POWER_MODE_OFF);
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, powerMode=%d, numLayers=%zu\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, mPowerMode, 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