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