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