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

Commit 875d8e13 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

Refactor SF. Move all GL operations in their own class.

this is the first step to add support for GLES 2.x, this
change breaks the dependency of SF on GLES 1.x by moving
all operation into their own class.

Bug: 8679321

Change-Id: I0d2741eca2cefe67dfd9cf837cac10c4d126928b
parent 9c3e2dd9
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@ LOCAL_SRC_FILES:= \
    DisplayDevice.cpp \
    EventThread.cpp \
    FrameTracker.cpp \
    GLExtensions.cpp \
    Layer.cpp \
    LayerDim.cpp \
    MessageQueue.cpp \
@@ -19,7 +18,12 @@ LOCAL_SRC_FILES:= \
    DisplayHardware/PowerHAL.cpp \
    DisplayHardware/VirtualDisplaySurface.cpp \
    EventLog/EventLogTags.logtags \
    EventLog/EventLog.cpp
    EventLog/EventLog.cpp \
    RenderEngine/GLExtensions.cpp \
    RenderEngine/RenderEngine.cpp \
    RenderEngine/GLES10RenderEngine.cpp \
    RenderEngine/GLES11RenderEngine.cpp


LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+10 −34
Original line number Diff line number Diff line
@@ -29,18 +29,14 @@

#include <gui/Surface.h>

#include <GLES/gl.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <hardware/gralloc.h>

#include "DisplayHardware/DisplaySurface.h"
#include "DisplayHardware/HWComposer.h"
#include "RenderEngine/RenderEngine.h"

#include "clz.h"
#include "DisplayDevice.h"
#include "GLExtensions.h"
#include "SurfaceFlinger.h"
#include "Layer.h"

@@ -48,20 +44,6 @@
using namespace android;
// ----------------------------------------------------------------------------

static __attribute__((noinline))
void checkGLErrors()
{
    do {
        // there could be more than one error flag
        GLenum error = glGetError();
        if (error == GL_NO_ERROR)
            break;
        ALOGE("GL error 0x%04x", int(error));
    } while(true);
}

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

/*
 * Initialize the display to the specified values.
 *
@@ -189,7 +171,7 @@ status_t DisplayDevice::compositionComplete() const {

void DisplayDevice::flip(const Region& dirty) const
{
    checkGLErrors();
    mFlinger->getRenderEngine().checkErrors();

    EGLDisplay dpy = mDisplay;
    EGLSurface surface = mSurface;
@@ -246,28 +228,22 @@ uint32_t DisplayDevice::getFlags() const
    return mFlags;
}

EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy,
        const sp<const DisplayDevice>& hw, EGLContext ctx) {
EGLBoolean DisplayDevice::makeCurrent(EGLDisplay dpy, EGLContext ctx) const {
    EGLBoolean result = EGL_TRUE;
    EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
    if (sur != hw->mSurface) {
        result = eglMakeCurrent(dpy, hw->mSurface, hw->mSurface, ctx);
    if (sur != mSurface) {
        result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
        if (result == EGL_TRUE) {
            setViewportAndProjection(hw);
            setViewportAndProjection();
        }
    }
    return result;
}

void DisplayDevice::setViewportAndProjection(const sp<const DisplayDevice>& hw) {
    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
    glMatrixMode(GL_MODELVIEW);
void DisplayDevice::setViewportAndProjection() const {
    size_t w = mDisplayWidth;
    size_t h = mDisplayHeight;
    mFlinger->getRenderEngine().setViewportAndProjection(w, h);
}

// ----------------------------------------------------------------------------
+2 −4
Original line number Diff line number Diff line
@@ -133,10 +133,8 @@ public:
    void setDisplayName(const String8& displayName);
    const String8& getDisplayName() const { return mDisplayName; }

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

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

    /* ------------------------------------------------------------------------
     * blank / unblank management
+26 −150
Original line number Diff line number Diff line
@@ -38,13 +38,14 @@
#include "clz.h"
#include "Colorizer.h"
#include "DisplayDevice.h"
#include "GLExtensions.h"
#include "Layer.h"
#include "SurfaceFlinger.h"
#include "SurfaceTextureLayer.h"

#include "DisplayHardware/HWComposer.h"

#include "RenderEngine/RenderEngine.h"

#define DEBUG_RESIZE    0

namespace android {
@@ -63,7 +64,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
        mName("unnamed"),
        mDebug(false),
        mFormat(PIXEL_FORMAT_NONE),
        mGLExtensions(GLExtensions::getInstance()),
        mOpaqueLayer(true),
        mTransactionFlags(0),
        mQueuedFrames(0),
@@ -236,15 +236,6 @@ sp<BufferQueue> Layer::getBufferQueue() const {
    return mSurfaceFlingerConsumer->getBufferQueue();
}

//virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
//    sp<IGraphicBufferProducer> res;
//    sp<const Layer> that( mOwner.promote() );
//    if (that != NULL) {
//        res = that->mSurfaceFlingerConsumer->getBufferQueue();
//    }
//    return res;
//}

// ---------------------------------------------------------------------------
// h/w composer set-up
// ---------------------------------------------------------------------------
@@ -499,6 +490,8 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const

    bool blackOutLayer = isProtected() || (isSecure() && !hw->isSecure());

    RenderEngine& engine(mFlinger->getRenderEngine());

    if (!blackOutLayer) {
        // TODO: we could be more subtle with isFixedSize()
        const bool useFiltering = getFiltering() || needsFiltering(hw) || isFixedSize();
@@ -509,49 +502,24 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
        mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);

        // Set things up for texturing.
        glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureName);
        GLenum filter = GL_NEAREST;
        if (useFiltering) {
            filter = GL_LINEAR;
        }
        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
        glMatrixMode(GL_TEXTURE);
        glLoadMatrixf(textureMatrix);
        glMatrixMode(GL_MODELVIEW);
        glDisable(GL_TEXTURE_2D);
        glEnable(GL_TEXTURE_EXTERNAL_OES);
        engine.setupLayerTexturing(mTextureName, useFiltering, textureMatrix);
    } else {
        glBindTexture(GL_TEXTURE_2D, mFlinger->getProtectedTexName());
        glMatrixMode(GL_TEXTURE);
        glLoadIdentity();
        glMatrixMode(GL_MODELVIEW);
        glDisable(GL_TEXTURE_EXTERNAL_OES);
        glEnable(GL_TEXTURE_2D);
        engine.setupLayerBlackedOut();
    }

    drawWithOpenGL(hw, clip);

    glDisable(GL_TEXTURE_EXTERNAL_OES);
    glDisable(GL_TEXTURE_2D);
    engine.disableTexturing();
}


void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
        GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
{
    const uint32_t fbHeight = hw->getHeight();
    glColor4f(red,green,blue,alpha);

    glDisable(GL_TEXTURE_EXTERNAL_OES);
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

    LayerMesh mesh;
    computeGeometry(hw, &mesh);

    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
    mFlinger->getRenderEngine().clearWithColor(
        mesh.getVertices(), mesh.getVertexCount(),
        red, green, blue, alpha);
}

void Layer::clearWithOpenGL(
@@ -559,102 +527,14 @@ void Layer::clearWithOpenGL(
    clearWithOpenGL(hw, clip, 0,0,0,0);
}

static void setupOpenGL10(bool premultipliedAlpha, bool opaque, int alpha) {
    // OpenGL ES 1.0 doesn't support texture combiners.
    // This path doesn't properly handle opaque layers that have non-opaque
    // alpha values. The alpha channel will be copied into the framebuffer or
    // screenshot, so if the framebuffer or screenshot is blended on top of
    // something else,  whatever is below the window will incorrectly show
    // through.
    if (CC_UNLIKELY(alpha < 0xFF)) {
        GLfloat floatAlpha = alpha * (1.0f / 255.0f);
        if (premultipliedAlpha) {
            glColor4f(floatAlpha, floatAlpha, floatAlpha, floatAlpha);
        } else {
            glColor4f(1.0f, 1.0f, 1.0f, floatAlpha);
        }
        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    } else {
        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    }
}

static void setupOpenGL11(bool premultipliedAlpha, bool opaque, int alpha) {
    GLenum combineRGB;
    GLenum combineAlpha;
    GLenum src0Alpha;
    GLfloat envColor[4];

    if (CC_UNLIKELY(alpha < 0xFF)) {
        // Cv = premultiplied ? Cs*alpha : Cs
        // Av = !opaque       ? alpha*As : 1.0
        combineRGB   = premultipliedAlpha ? GL_MODULATE : GL_REPLACE;
        combineAlpha = !opaque            ? GL_MODULATE : GL_REPLACE;
        src0Alpha    = GL_CONSTANT;
        envColor[0]  = alpha * (1.0f / 255.0f);
    } else {
        // Cv = Cs
        // Av = opaque ? 1.0 : As
        combineRGB   = GL_REPLACE;
        combineAlpha = GL_REPLACE;
        src0Alpha    = opaque ? GL_CONSTANT : GL_TEXTURE;
        envColor[0]  = 1.0f;
    }

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, combineRGB);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
    if (combineRGB == GL_MODULATE) {
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
    }
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, combineAlpha);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, src0Alpha);
    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
    if (combineAlpha == GL_MODULATE) {
        glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
        glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
    }
    if (combineRGB == GL_MODULATE || src0Alpha == GL_CONSTANT) {
        envColor[1] = envColor[0];
        envColor[2] = envColor[0];
        envColor[3] = envColor[0];
        glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, envColor);
    }
}

void Layer::drawWithOpenGL(
        const sp<const DisplayDevice>& hw, const Region& clip) const {
    const uint32_t fbHeight = hw->getHeight();
    const State& s(getDrawingState());

    if (mFlinger->getGlesVersion() == GLES_VERSION_1_0) {
        setupOpenGL10(mPremultipliedAlpha, isOpaque(), s.alpha);
    } else {
        setupOpenGL11(mPremultipliedAlpha, isOpaque(), s.alpha);
    }

    if (s.alpha < 0xFF || !isOpaque()) {
        glEnable(GL_BLEND);
        glBlendFunc(mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA,
                    GL_ONE_MINUS_SRC_ALPHA);
    } else {
        glDisable(GL_BLEND);
    }

    LayerMesh mesh;
    computeGeometry(hw, &mesh);

    // TODO: we probably want to generate the texture coords with the mesh
    // here we assume that we only have 4 vertices

    struct TexCoords {
        GLfloat u;
        GLfloat v;
    };


    /*
     * NOTE: the way we compute the texture coordinates here produces
     * different results than when we take the HWC path -- in the later case
@@ -676,26 +556,25 @@ void Layer::drawWithOpenGL(
    GLfloat right  = GLfloat(win.right)  / GLfloat(s.active.w);
    GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);

    TexCoords texCoords[4];
    texCoords[0].u = left;
    texCoords[0].v = top;
    texCoords[1].u = left;
    texCoords[1].v = bottom;
    texCoords[2].u = right;
    texCoords[2].v = bottom;
    texCoords[3].u = right;
    texCoords[3].v = top;
    // TODO: we probably want to generate the texture coords with the mesh
    // here we assume that we only have 4 vertices
    float texCoords[4][2];
    texCoords[0][0] = left;
    texCoords[0][1] = top;
    texCoords[1][0] = left;
    texCoords[1][1] = bottom;
    texCoords[2][0] = right;
    texCoords[2][1] = bottom;
    texCoords[3][0] = right;
    texCoords[3][1] = top;
    for (int i = 0; i < 4; i++) {
        texCoords[i].v = 1.0f - texCoords[i].v;
        texCoords[i][1] = 1.0f - texCoords[i][1];
    }

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());

    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_BLEND);
    RenderEngine& engine(mFlinger->getRenderEngine());
    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
    engine.drawMesh2D(mesh.getVertices(), texCoords, mesh.getVertexCount());
    engine.disableBlending();
}

void Layer::setFiltering(bool filtering) {
@@ -1209,9 +1088,6 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
            recomputeVisibleRegions = true;
        }

        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // FIXME: postedRegion should be dirty & bounds
        const Layer::State& s(getDrawingState());
        Region dirtyRegion(Rect(s.active.w, s.active.h));
+4 −7
Original line number Diff line number Diff line
@@ -22,8 +22,6 @@

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>

#include <utils/RefBase.h>
#include <utils/String8.h>
@@ -55,7 +53,6 @@ class Colorizer;
class DisplayDevice;
class GraphicBuffer;
class SurfaceFlinger;
class GLExtensions;

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

@@ -113,14 +110,15 @@ public:

    class LayerMesh {
        friend class Layer;
        GLfloat mVertices[4][2];
        typedef GLfloat float2[2];
        float2 mVertices[4];
        size_t mNumVertices;
    public:
        LayerMesh() :
                mNumVertices(4) {
        }
        GLfloat const* getVertices() const {
            return &mVertices[0][0];
        float2 const* getVertices() const {
            return mVertices;
        }
        size_t getVertexCount() const {
            return mNumVertices;
@@ -355,7 +353,6 @@ private:
    String8 mName;
    mutable bool mDebug;
    PixelFormat mFormat;
    const GLExtensions& mGLExtensions;
    bool mOpaqueLayer;

    // these are protected by an external lock
Loading