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