Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84eda044 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android Git Automerger
Browse files

am da8d0a5c: implement display viewport and frame

* commit 'da8d0a5c':
  implement display viewport and frame
parents e4f7d56e da8d0a5c
Loading
Loading
Loading
Loading
+85 −16
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/HWComposer.h"

#include "clz.h"
#include "DisplayDevice.h"
#include "GLExtensions.h"
#include "SurfaceFlinger.h"
@@ -84,8 +85,8 @@ DisplayDevice::DisplayDevice(
      mPageFlipCount(),
      mSecureLayerVisible(false),
      mScreenAcquired(false),
      mOrientation(),
      mLayerStack(0)
      mLayerStack(0),
      mOrientation()
{
    init(config);
}
@@ -139,6 +140,8 @@ void DisplayDevice::init(EGLConfig config)
    mSurface = surface;
    mFormat  = format;
    mPageFlipCount = 0;
    mViewport.makeInvalid();
    mFrame.makeInvalid();

    // external displays are always considered enabled
    mScreenAcquired = (mType >= DisplayDevice::NUM_DISPLAY_TYPES);
@@ -192,13 +195,24 @@ void DisplayDevice::dump(String8& res) const
    }
}

void DisplayDevice::makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx) {
EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy,
        const sp<const DisplayDevice>& hw, EGLContext ctx) {
    EGLBoolean result = EGL_TRUE;
    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
    if (sur != hw->mSurface) {
        EGLDisplay dpy = eglGetCurrentDisplay();
        eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
        result = eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
        if (result == EGL_TRUE) {
            GLsizei w = hw->mDisplayWidth;
            GLsizei h = hw->mDisplayHeight;
            glViewport(0, 0, w, h);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            // put the origin in the left-bottom corner
            glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h
        }
    }
    return result;
}

// ----------------------------------------------------------------------------

@@ -223,10 +237,10 @@ bool DisplayDevice::getSecureLayerVisible() const {

Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
    Region dirty;
    const Transform& planeTransform(mGlobalTransform);
    if (repaintEverything) {
        dirty.set(getBounds());
    } else {
        const Transform& planeTransform(mGlobalTransform);
        dirty = planeTransform.transform(this->dirtyRegion);
        dirty.andSelf(getBounds());
    }
@@ -284,18 +298,73 @@ status_t DisplayDevice::orientationToTransfrom(
    return NO_ERROR;
}

status_t DisplayDevice::setOrientation(int orientation) {
void DisplayDevice::setOrientation(int orientation) {
    mOrientation = orientation;
    updateGeometryTransform();
}

void DisplayDevice::setViewport(const Rect& viewport) {
    if (viewport.isValid()) {
        mViewport = viewport;
        updateGeometryTransform();
    }
}

void DisplayDevice::setFrame(const Rect& frame) {
    if (frame.isValid()) {
        mFrame = frame;
        updateGeometryTransform();
    }
}

void DisplayDevice::updateGeometryTransform() {
    int w = mDisplayWidth;
    int h = mDisplayHeight;
    Transform R, S;
    if (DisplayDevice::orientationToTransfrom(
            mOrientation, w, h, &R) == NO_ERROR) {
        dirtyRegion.set(bounds());

        Rect viewport(mViewport);
        Rect frame(mFrame);

    DisplayDevice::orientationToTransfrom(
            orientation, w, h, &mGlobalTransform);
    if (orientation & DisplayState::eOrientationSwapMask) {
        int tmp = w;
        w = h;
        h = tmp;
        if (!frame.isValid()) {
            // the destination frame can be invalid if it has never been set,
            // in that case we assume the whole display frame.
            frame = Rect(w, h);
        }

        if (viewport.isEmpty()) {
            // viewport can be invalid if it has never been set, in that case
            // we assume the whole display size.
            // it's also invalid to have an empty viewport, so we handle that
            // case in the same way.
            viewport = Rect(w, h);
            if (R.getOrientation() & Transform::ROT_90) {
                // viewport is always specified in the logical orientation
                // of the display (ie: post-rotation).
                swap(viewport.right, viewport.bottom);
            }
        }

        float src_width  = viewport.width();
        float src_height = viewport.height();
        float dst_width  = frame.width();
        float dst_height = frame.height();
        if (src_width != src_height || dst_width != dst_height) {
            float sx = dst_width  / src_width;
            float sy = dst_height / src_height;
            S.set(sx, 0, 0, sy);
        }
        float src_x = viewport.left;
        float src_y = viewport.top;
        float dst_x = frame.left;
        float dst_y = frame.top;
        float tx = dst_x - src_x;
        float ty = dst_y - src_y;
        S.set(tx, ty);

        // rotate first, followed by scaling
        mGlobalTransform = S * R;
    }
    mOrientation = orientation;
    dirtyRegion.set(bounds());
    return NO_ERROR;
}
+17 −6
Original line number Diff line number Diff line
@@ -93,11 +93,16 @@ public:
    bool                    getSecureLayerVisible() const;
    Region                  getDirtyRegion(bool repaintEverything) const;

    status_t                setOrientation(int orientation);
    void                    setLayerStack(uint32_t stack);
    void                    setOrientation(int orientation);
    void                    setViewport(const Rect& viewport);
    void                    setFrame(const Rect& frame);

    int                     getOrientation() const { return mOrientation; }
    const Transform&        getTransform() const { return mGlobalTransform; }
    const Rect&             getViewport() const { return mViewport; }
    const Rect&             getFrame() const { return mFrame; }

    uint32_t                getLayerStack() const { return mLayerStack; }
    int32_t                 getDisplayType() const { return mType; }
    int32_t                 getHwcDisplayId() const { return mHwcDisplayId; }
@@ -110,7 +115,8 @@ public:
    }
    inline Rect bounds() const { return getBounds(); }

    static void makeCurrent(const sp<const DisplayDevice>& hw, EGLContext ctx);
    static EGLBoolean makeCurrent(EGLDisplay dpy,
            const sp<const DisplayDevice>& hw, EGLContext ctx);

    /* ------------------------------------------------------------------------
     * blank / unplank management
@@ -170,11 +176,16 @@ private:
    /*
     * Transaction state
     */
    static status_t orientationToTransfrom(int orientation, int w, int h,
            Transform* tr);
    Transform mGlobalTransform;
    int mOrientation;
    static status_t orientationToTransfrom(int orientation,
            int w, int h, Transform* tr);

    void updateGeometryTransform();

    uint32_t mLayerStack;
    int mOrientation;
    Rect mViewport;
    Rect mFrame;
    Transform mGlobalTransform;
};

}; // namespace android
+22 −24
Original line number Diff line number Diff line
@@ -297,8 +297,8 @@ EGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config)
    return ctxt;
}

void SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
    EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext);
void SurfaceFlinger::initializeGL(EGLDisplay display, const sp<DisplayDevice>& hw) {
    EGLBoolean result = DisplayDevice::makeCurrent(display, hw, mEGLContext);
    if (!result) {
        ALOGE("Couldn't create a working GLES context. check logs. exiting...");
        exit(0);
@@ -314,10 +314,6 @@ void SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
            eglQueryString(display, EGL_VERSION),
            eglQueryString(display, EGL_EXTENSIONS));

    EGLint w, h;
    eglQuerySurface(display, surface, EGL_WIDTH,  &w);
    eglQuerySurface(display, surface, EGL_HEIGHT, &h);

    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);

@@ -344,12 +340,6 @@ void SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) {
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0,
            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData);

    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    // put the origin in the left-bottom corner
    glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h

    // print some debugging info
    EGLint r,g,b,a;
    eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE,   &r);
@@ -412,8 +402,7 @@ status_t SurfaceFlinger::readyToRun()
    mDisplays.add(mDefaultDisplays[DisplayDevice::DISPLAY_PRIMARY], hw);

    //  initialize OpenGL ES
    EGLSurface surface = hw->getEGLSurface();
    initializeGL(mEGLDisplay, surface);
    initializeGL(mEGLDisplay, hw);

    // start the EventThread
    mEventThread = new EventThread(this);
@@ -863,7 +852,7 @@ void SurfaceFlinger::postFramebuffer()
        // FIXME: EGL spec says:
        //   "surface must be bound to the calling thread's current context,
        //    for the current rendering API."
        DisplayDevice::makeCurrent(getDefaultDisplayDevice(), mEGLContext);
        DisplayDevice::makeCurrent(mEGLDisplay, getDefaultDisplayDevice(), mEGLContext);
        hwc.commit();
    }

@@ -983,11 +972,14 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                        if (state.layerStack != draw[i].layerStack) {
                            disp->setLayerStack(state.layerStack);
                        }
                        if (state.orientation != draw[i].orientation ||
                                state.viewport != draw[i].viewport ||
                                state.frame != draw[i].frame) {
                        if (state.orientation != draw[i].orientation) {
                            disp->setOrientation(state.orientation);
                            // TODO: take viewport and frame into account
                        }
                        if (state.viewport != draw[i].viewport) {
                            disp->setViewport(state.viewport);
                        }
                        if (state.frame != draw[i].frame) {
                            disp->setFrame(state.frame);
                        }
                    }
                }
@@ -1006,7 +998,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                                state.type, display, stc, 0, mEGLConfig);
                        disp->setLayerStack(state.layerStack);
                        disp->setOrientation(state.orientation);
                        // TODO: take viewport and frame into account
                        disp->setViewport(state.viewport);
                        disp->setFrame(state.frame);
                        mDisplays.add(display, disp);
                    }
                }
@@ -1280,7 +1273,7 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const

    const bool hasGlesComposition = hwc.hasGlesComposition(id) || (cur==end);
    if (hasGlesComposition) {
        DisplayDevice::makeCurrent(hw, mEGLContext);
        DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);

        // set the frame buffer
        glMatrixMode(GL_MODELVIEW);
@@ -1977,15 +1970,18 @@ void SurfaceFlinger::dumpAllLocked(
        const sp<const DisplayDevice>& hw(mDisplays[dpy]);
        snprintf(buffer, SIZE,
                "+ DisplayDevice[%u]\n"
                "   id=%x, layerStack=%u, (%4dx%4d), orient=%2d, tr=%08x, "
                "flips=%u, secure=%d, numLayers=%u\n",
                "   id=%x, layerStack=%u, (%4dx%4d), orient=%2d (type=%08x), "
                "flips=%u, secure=%d, numLayers=%u, v:[%d,%d,%d,%d], f:[%d,%d,%d,%d]\n",
                dpy,
                hw->getDisplayType(), hw->getLayerStack(),
                hw->getWidth(), hw->getHeight(),
                hw->getOrientation(), hw->getTransform().getType(),
                hw->getPageFlipCount(),
                hw->getSecureLayerVisible(),
                hw->getVisibleLayersSortedByZ().size());
                hw->getVisibleLayersSortedByZ().size(),
                hw->getViewport().left, hw->getViewport().top, hw->getViewport().right, hw->getViewport().bottom,
                hw->getFrame().left, hw->getFrame().top, hw->getFrame().right, hw->getFrame().bottom);

        result.append(buffer);
    }

@@ -2488,6 +2484,8 @@ SurfaceFlinger::DisplayDeviceState::DisplayDeviceState()

SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type)
    : type(type), layerStack(0), orientation(0) {
    viewport.makeInvalid();
    frame.makeInvalid();
}

// ---------------------------------------------------------------------------
+1 −1
Original line number Diff line number Diff line
@@ -320,7 +320,7 @@ private:
        EGLint const* attrs, PixelFormat format, EGLConfig* outConfig);
    static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId);
    static EGLContext createGLContext(EGLDisplay disp, EGLConfig config);
    void initializeGL(EGLDisplay display, EGLSurface surface);
    void initializeGL(EGLDisplay display, const sp<DisplayDevice>& hw);
    uint32_t getMaxTextureSize() const;
    uint32_t getMaxViewportDims() const;