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