DisplayDevice.cpp revision 514e30a96cefad109509ce01622fa7f82f3f318c
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      mScreenAcquired(false),
75      mLayerStack(NO_LAYER_STACK),
76      mOrientation()
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    mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);
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#endif
199
200    mPageFlipCount++;
201}
202
203status_t DisplayDevice::beginFrame(bool mustRecompose) const {
204    return mDisplaySurface->beginFrame(mustRecompose);
205}
206
207status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
208    DisplaySurface::CompositionType compositionType;
209    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
210    bool haveHwc = hwc.hasHwcComposition(mHwcDisplayId);
211    if (haveGles && haveHwc) {
212        compositionType = DisplaySurface::COMPOSITION_MIXED;
213    } else if (haveGles) {
214        compositionType = DisplaySurface::COMPOSITION_GLES;
215    } else if (haveHwc) {
216        compositionType = DisplaySurface::COMPOSITION_HWC;
217    } else {
218        // Nothing to do -- when turning the screen off we get a frame like
219        // this. Call it a HWC frame since we won't be doing any GLES work but
220        // will do a prepare/set cycle.
221        compositionType = DisplaySurface::COMPOSITION_HWC;
222    }
223    return mDisplaySurface->prepareFrame(compositionType);
224}
225
226void DisplayDevice::swapBuffers(HWComposer& hwc) const {
227    // We need to call eglSwapBuffers() if:
228    //  (1) we don't have a hardware composer, or
229    //  (2) we did GLES composition this frame, and either
230    //    (a) we have framebuffer target support (not present on legacy
231    //        devices, where HWComposer::commit() handles things); or
232    //    (b) this is a virtual display
233    if (hwc.initCheck() != NO_ERROR ||
234            (hwc.hasGlesComposition(mHwcDisplayId) &&
235             (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
236        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
237        if (!success) {
238            EGLint error = eglGetError();
239            if (error == EGL_CONTEXT_LOST ||
240                    mType == DisplayDevice::DISPLAY_PRIMARY) {
241                LOG_ALWAYS_FATAL("eglSwapBuffers(%p, %p) failed with 0x%08x",
242                        mDisplay, mSurface, error);
243            } else {
244                ALOGE("eglSwapBuffers(%p, %p) failed with 0x%08x",
245                        mDisplay, mSurface, error);
246            }
247        }
248    }
249
250    status_t result = mDisplaySurface->advanceFrame();
251    if (result != NO_ERROR) {
252        ALOGE("[%s] failed pushing new frame to HWC: %d",
253                mDisplayName.string(), result);
254    }
255}
256
257void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
258    if (hwc.initCheck() == NO_ERROR) {
259        mDisplaySurface->onFrameCommitted();
260    }
261}
262
263uint32_t DisplayDevice::getFlags() const
264{
265    return mFlags;
266}
267
268EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
269    EGLBoolean result = EGL_TRUE;
270    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
271    if (sur != mSurface) {
272        result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
273        if (result == EGL_TRUE) {
274            if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
275                eglSwapInterval(dpy, 0);
276        }
277    }
278    setViewportAndProjection();
279    return result;
280}
281
282void DisplayDevice::setViewportAndProjection() const {
283    size_t w = mDisplayWidth;
284    size_t h = mDisplayHeight;
285    mFlinger->getRenderEngine().setViewportAndProjection(w, h, w, h, false);
286}
287
288// ----------------------------------------------------------------------------
289
290void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
291    mVisibleLayersSortedByZ = layers;
292    mSecureLayerVisible = false;
293    size_t count = layers.size();
294    for (size_t i=0 ; i<count ; i++) {
295        const sp<Layer>& layer(layers[i]);
296        if (layer->isSecure()) {
297            mSecureLayerVisible = true;
298        }
299    }
300}
301
302const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
303    return mVisibleLayersSortedByZ;
304}
305
306bool DisplayDevice::getSecureLayerVisible() const {
307    return mSecureLayerVisible;
308}
309
310Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
311    Region dirty;
312    if (repaintEverything) {
313        dirty.set(getBounds());
314    } else {
315        const Transform& planeTransform(mGlobalTransform);
316        dirty = planeTransform.transform(this->dirtyRegion);
317        dirty.andSelf(getBounds());
318    }
319    return dirty;
320}
321
322// ----------------------------------------------------------------------------
323
324bool DisplayDevice::canDraw() const {
325    return mScreenAcquired;
326}
327
328void DisplayDevice::releaseScreen() const {
329    mScreenAcquired = false;
330}
331
332void DisplayDevice::acquireScreen() const {
333    mScreenAcquired = true;
334}
335
336bool DisplayDevice::isScreenAcquired() const {
337    return mScreenAcquired;
338}
339
340// ----------------------------------------------------------------------------
341
342void DisplayDevice::setLayerStack(uint32_t stack) {
343    mLayerStack = stack;
344    dirtyRegion.set(bounds());
345}
346
347// ----------------------------------------------------------------------------
348
349uint32_t DisplayDevice::getOrientationTransform() const {
350    uint32_t transform = 0;
351    switch (mOrientation) {
352        case DisplayState::eOrientationDefault:
353            transform = Transform::ROT_0;
354            break;
355        case DisplayState::eOrientation90:
356            transform = Transform::ROT_90;
357            break;
358        case DisplayState::eOrientation180:
359            transform = Transform::ROT_180;
360            break;
361        case DisplayState::eOrientation270:
362            transform = Transform::ROT_270;
363            break;
364    }
365    return transform;
366}
367
368status_t DisplayDevice::orientationToTransfrom(
369        int orientation, int w, int h, Transform* tr)
370{
371    uint32_t flags = 0;
372    switch (orientation) {
373    case DisplayState::eOrientationDefault:
374        flags = Transform::ROT_0;
375        break;
376    case DisplayState::eOrientation90:
377        flags = Transform::ROT_90;
378        break;
379    case DisplayState::eOrientation180:
380        flags = Transform::ROT_180;
381        break;
382    case DisplayState::eOrientation270:
383        flags = Transform::ROT_270;
384        break;
385    default:
386        return BAD_VALUE;
387    }
388    tr->set(flags, w, h);
389    return NO_ERROR;
390}
391
392void DisplayDevice::setProjection(int orientation,
393        const Rect& newViewport, const Rect& newFrame) {
394    Rect viewport(newViewport);
395    Rect frame(newFrame);
396
397    const int w = mDisplayWidth;
398    const int h = mDisplayHeight;
399
400    Transform R;
401    DisplayDevice::orientationToTransfrom(orientation, w, h, &R);
402
403    if (!frame.isValid()) {
404        // the destination frame can be invalid if it has never been set,
405        // in that case we assume the whole display frame.
406        frame = Rect(w, h);
407    }
408
409    if (viewport.isEmpty()) {
410        // viewport can be invalid if it has never been set, in that case
411        // we assume the whole display size.
412        // it's also invalid to have an empty viewport, so we handle that
413        // case in the same way.
414        viewport = Rect(w, h);
415        if (R.getOrientation() & Transform::ROT_90) {
416            // viewport is always specified in the logical orientation
417            // of the display (ie: post-rotation).
418            swap(viewport.right, viewport.bottom);
419        }
420    }
421
422    dirtyRegion.set(getBounds());
423
424    Transform TL, TP, S;
425    float src_width  = viewport.width();
426    float src_height = viewport.height();
427    float dst_width  = frame.width();
428    float dst_height = frame.height();
429    if (src_width != dst_width || src_height != dst_height) {
430        float sx = dst_width  / src_width;
431        float sy = dst_height / src_height;
432        S.set(sx, 0, 0, sy);
433    }
434
435    float src_x = viewport.left;
436    float src_y = viewport.top;
437    float dst_x = frame.left;
438    float dst_y = frame.top;
439    TL.set(-src_x, -src_y);
440    TP.set(dst_x, dst_y);
441
442    // The viewport and frame are both in the logical orientation.
443    // Apply the logical translation, scale to physical size, apply the
444    // physical translation and finally rotate to the physical orientation.
445    mGlobalTransform = R * TP * S * TL;
446
447    const uint8_t type = mGlobalTransform.getType();
448    mNeedsFiltering = (!mGlobalTransform.preserveRects() ||
449            (type >= Transform::SCALE));
450
451    mScissor = mGlobalTransform.transform(viewport);
452    if (mScissor.isEmpty()) {
453        mScissor = getBounds();
454    }
455
456    mOrientation = orientation;
457    mViewport = viewport;
458    mFrame = frame;
459}
460
461void DisplayDevice::dump(String8& result) const {
462    const Transform& tr(mGlobalTransform);
463    result.appendFormat(
464        "+ DisplayDevice: %s\n"
465        "   type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
466        "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%zu\n"
467        "   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
468        "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
469        mDisplayName.string(), mType, mHwcDisplayId,
470        mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
471        mOrientation, tr.getType(), getPageFlipCount(),
472        mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
473        mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
474        mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
475        mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
476        tr[0][0], tr[1][0], tr[2][0],
477        tr[0][1], tr[1][1], tr[2][1],
478        tr[0][2], tr[1][2], tr[2][2]);
479
480    String8 surfaceDump;
481    mDisplaySurface->dump(surfaceDump);
482    result.append(surfaceDump);
483}
484