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