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