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