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