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

Commit 9e56aa0f authored by Dan Stoza's avatar Dan Stoza
Browse files

Switch SurfaceFlinger to HWC 2.0

Enables SurfaceFlinger to speak to version 2.0 of the Hardware Composer
HAL instead of version 1.x (also removing support for the framebuffer
HAL). By default, however, this functionality is disabled. In order to
enable it, USE_HWC2 must be set to true in Android.mk.

Change-Id: I4589e02ac2165236b10ff2f7cb772f87e0d3daab
parent fc4e202b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ public:
    // when the current buffer is released by updateTexImage(). Multiple
    // fences can be set for a given buffer; they will be merged into a single
    // union fence.
    void setReleaseFence(const sp<Fence>& fence);
    virtual void setReleaseFence(const sp<Fence>& fence);

    // getTransformMatrix retrieves the 4x4 texture coordinate transform matrix
    // associated with the texture image set by the most recent call to
+13 −2
Original line number Diff line number Diff line
@@ -15,13 +15,11 @@ LOCAL_SRC_FILES := \
    LayerDim.cpp \
    MessageQueue.cpp \
    MonitoredProducer.cpp \
    SurfaceFlinger.cpp \
    SurfaceFlingerConsumer.cpp \
    Transform.cpp \
    DisplayHardware/FramebufferSurface.cpp \
    DisplayHardware/HWC2.cpp \
    DisplayHardware/HWC2On1Adapter.cpp \
    DisplayHardware/HWComposer.cpp \
    DisplayHardware/PowerHAL.cpp \
    DisplayHardware/VirtualDisplaySurface.cpp \
    Effects/Daltonizer.cpp \
@@ -42,6 +40,19 @@ LOCAL_SRC_FILES := \
LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES


USE_HWC2 := false
ifeq ($(USE_HWC2),true)
    LOCAL_CFLAGS += -DUSE_HWC2
    LOCAL_SRC_FILES += \
        SurfaceFlinger.cpp \
        DisplayHardware/HWComposer.cpp
else
    LOCAL_SRC_FILES += \
        SurfaceFlinger_hwc1.cpp \
        DisplayHardware/HWComposer_hwc1.cpp
endif

ifeq ($(TARGET_BOARD_PLATFORM),omap4)
    LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
endif
+71 −3
Original line number Diff line number Diff line
@@ -14,6 +14,10 @@
 * limitations under the License.
 */

// #define LOG_NDEBUG 0
#undef LOG_TAG
#define LOG_TAG "DisplayDevice"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -33,6 +37,9 @@

#include "DisplayHardware/DisplaySurface.h"
#include "DisplayHardware/HWComposer.h"
#ifdef USE_HWC2
#include "DisplayHardware/HWC2.h"
#endif
#include "RenderEngine/RenderEngine.h"

#include "clz.h"
@@ -65,7 +72,9 @@ DisplayDevice::DisplayDevice(
        const sp<SurfaceFlinger>& flinger,
        DisplayType type,
        int32_t hwcId,
#ifndef USE_HWC2
        int format,
#endif
        bool isSecure,
        const wp<IBinder>& displayToken,
        const sp<DisplaySurface>& displaySurface,
@@ -73,12 +82,17 @@ DisplayDevice::DisplayDevice(
        EGLConfig config)
    : lastCompositionHadVisibleLayers(false),
      mFlinger(flinger),
      mType(type), mHwcDisplayId(hwcId),
      mType(type),
      mHwcDisplayId(hwcId),
      mDisplayToken(displayToken),
      mDisplaySurface(displaySurface),
      mDisplay(EGL_NO_DISPLAY),
      mSurface(EGL_NO_SURFACE),
      mDisplayWidth(), mDisplayHeight(), mFormat(),
      mDisplayWidth(),
      mDisplayHeight(),
#ifndef USE_HWC2
      mFormat(),
#endif
      mFlags(),
      mPageFlipCount(),
      mIsSecure(isSecure),
@@ -98,7 +112,11 @@ DisplayDevice::DisplayDevice(
    EGLSurface eglSurface;
    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (config == EGL_NO_CONFIG) {
#ifdef USE_HWC2
        config = RenderEngine::chooseEglConfig(display, PIXEL_FORMAT_RGBA_8888);
#else
        config = RenderEngine::chooseEglConfig(display, format);
#endif
    }
    eglSurface = eglCreateWindowSurface(display, config, window, NULL);
    eglQuerySurface(display, eglSurface, EGL_WIDTH,  &mDisplayWidth);
@@ -117,7 +135,9 @@ DisplayDevice::DisplayDevice(
    mConfig = config;
    mDisplay = display;
    mSurface = eglSurface;
#ifndef USE_HWC2
    mFormat = format;
#endif
    mPageFlipCount = 0;
    mViewport.makeInvalid();
    mFrame.makeInvalid();
@@ -158,8 +178,10 @@ DisplayDevice::~DisplayDevice() {
void DisplayDevice::disconnect(HWComposer& hwc) {
    if (mHwcDisplayId >= 0) {
        hwc.disconnectDisplay(mHwcDisplayId);
#ifndef USE_HWC2
        if (mHwcDisplayId >= DISPLAY_VIRTUAL)
            hwc.freeDisplayId(mHwcDisplayId);
#endif
        mHwcDisplayId = -1;
    }
}
@@ -176,9 +198,11 @@ int DisplayDevice::getHeight() const {
    return mDisplayHeight;
}

#ifndef USE_HWC2
PixelFormat DisplayDevice::getFormat() const {
    return mFormat;
}
#endif

EGLSurface DisplayDevice::getEGLSurface() const {
    return mSurface;
@@ -195,9 +219,11 @@ uint32_t DisplayDevice::getPageFlipCount() const {
    return mPageFlipCount;
}

#ifndef USE_HWC2
status_t DisplayDevice::compositionComplete() const {
    return mDisplaySurface->compositionComplete();
}
#endif

void DisplayDevice::flip(const Region& dirty) const
{
@@ -219,6 +245,31 @@ status_t DisplayDevice::beginFrame(bool mustRecompose) const {
    return mDisplaySurface->beginFrame(mustRecompose);
}

#ifdef USE_HWC2
status_t DisplayDevice::prepareFrame(HWComposer& hwc) {
    status_t error = hwc.prepare(*this);
    if (error != NO_ERROR) {
        return error;
    }

    DisplaySurface::CompositionType compositionType;
    bool hasClient = hwc.hasClientComposition(mHwcDisplayId);
    bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId);
    if (hasClient && hasDevice) {
        compositionType = DisplaySurface::COMPOSITION_MIXED;
    } else if (hasClient) {
        compositionType = DisplaySurface::COMPOSITION_GLES;
    } else if (hasDevice) {
        compositionType = DisplaySurface::COMPOSITION_HWC;
    } else {
        // Nothing to do -- when turning the screen off we get a frame like
        // this. Call it a HWC frame since we won't be doing any GLES work but
        // will do a prepare/set cycle.
        compositionType = DisplaySurface::COMPOSITION_HWC;
    }
    return mDisplaySurface->prepareFrame(compositionType);
}
#else
status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
    DisplaySurface::CompositionType compositionType;
    bool haveGles = hwc.hasGlesComposition(mHwcDisplayId);
@@ -237,8 +288,12 @@ status_t DisplayDevice::prepareFrame(const HWComposer& hwc) const {
    }
    return mDisplaySurface->prepareFrame(compositionType);
}
#endif

void DisplayDevice::swapBuffers(HWComposer& hwc) const {
#ifdef USE_HWC2
    if (hwc.hasClientComposition(mHwcDisplayId)) {
#else
    // We need to call eglSwapBuffers() if:
    //  (1) we don't have a hardware composer, or
    //  (2) we did GLES composition this frame, and either
@@ -248,6 +303,7 @@ void DisplayDevice::swapBuffers(HWComposer& hwc) const {
    if (hwc.initCheck() != NO_ERROR ||
            (hwc.hasGlesComposition(mHwcDisplayId) &&
             (hwc.supportsFramebufferTarget() || mType >= DISPLAY_VIRTUAL))) {
#endif
        EGLBoolean success = eglSwapBuffers(mDisplay, mSurface);
        if (!success) {
            EGLint error = eglGetError();
@@ -269,11 +325,17 @@ void DisplayDevice::swapBuffers(HWComposer& hwc) const {
    }
}

#ifdef USE_HWC2
void DisplayDevice::onSwapBuffersCompleted() const {
    mDisplaySurface->onFrameCommitted();
}
#else
void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
    if (hwc.initCheck() == NO_ERROR) {
        mDisplaySurface->onFrameCommitted();
    }
}
#endif

uint32_t DisplayDevice::getFlags() const
{
@@ -302,6 +364,12 @@ void DisplayDevice::setViewportAndProjection() const {
        false, Transform::ROT_0);
}

#ifdef USE_HWC2
const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
    return mDisplaySurface->getClientTargetAcquireFence();
}
#endif

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

void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
+35 −2
Original line number Diff line number Diff line
@@ -17,21 +17,31 @@
#ifndef ANDROID_DISPLAY_DEVICE_H
#define ANDROID_DISPLAY_DEVICE_H

#include "Transform.h"

#include <stdlib.h>

#ifndef USE_HWC2
#include <ui/PixelFormat.h>
#endif
#include <ui/Region.h>

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

#ifdef USE_HWC2
#include <binder/IBinder.h>
#include <utils/RefBase.h>
#endif
#include <utils/Mutex.h>
#include <utils/String8.h>
#include <utils/Timers.h>

#include <hardware/hwcomposer_defs.h>

#include "Transform.h"
#ifdef USE_HWC2
#include <memory>
#endif

struct ANativeWindow;

@@ -39,6 +49,9 @@ namespace android {

struct DisplayInfo;
class DisplaySurface;
#ifdef USE_HWC2
class Fence;
#endif
class IGraphicBufferProducer;
class Layer;
class SurfaceFlinger;
@@ -75,8 +88,10 @@ public:
    DisplayDevice(
            const sp<SurfaceFlinger>& flinger,
            DisplayType type,
            int32_t hwcId,  // negative for non-HWC-composited displays
            int32_t hwcId,
#ifndef USE_HWC2
            int format,
#endif
            bool isSecure,
            const wp<IBinder>& displayToken,
            const sp<DisplaySurface>& displaySurface,
@@ -99,7 +114,9 @@ public:

    int         getWidth() const;
    int         getHeight() const;
#ifndef USE_HWC2
    PixelFormat getFormat() const;
#endif
    uint32_t    getFlags() const;

    EGLSurface  getEGLSurface() const;
@@ -128,13 +145,23 @@ public:
    // We pass in mustRecompose so we can keep VirtualDisplaySurface's state
    // machine happy without actually queueing a buffer if nothing has changed
    status_t beginFrame(bool mustRecompose) const;
#ifdef USE_HWC2
    status_t prepareFrame(HWComposer& hwc);
#else
    status_t prepareFrame(const HWComposer& hwc) const;
#endif

    void swapBuffers(HWComposer& hwc) const;
#ifndef USE_HWC2
    status_t compositionComplete() const;
#endif

    // called after h/w composer has completed its set() call
#ifdef USE_HWC2
    void onSwapBuffersCompleted() const;
#else
    void onSwapBuffersCompleted(HWComposer& hwc) const;
#endif

    Rect getBounds() const {
        return Rect(mDisplayWidth, mDisplayHeight);
@@ -147,6 +174,10 @@ public:
    EGLBoolean makeCurrent(EGLDisplay dpy, EGLContext ctx) const;
    void setViewportAndProjection() const;

#ifdef USE_HWC2
    const sp<Fence>& getClientTargetAcquireFence() const;
#endif

    /* ------------------------------------------------------------------------
     * Display power mode management.
     */
@@ -187,7 +218,9 @@ private:
    EGLSurface      mSurface;
    int             mDisplayWidth;
    int             mDisplayHeight;
#ifndef USE_HWC2
    PixelFormat     mFormat;
#endif
    uint32_t        mFlags;
    mutable uint32_t mPageFlipCount;
    String8         mDisplayName;
+6 −0
Original line number Diff line number Diff line
@@ -49,11 +49,13 @@ public:
    };
    virtual status_t prepareFrame(CompositionType compositionType) = 0;

#ifndef USE_HWC2
    // Should be called when composition rendering is complete for a frame (but
    // eglSwapBuffers hasn't necessarily been called). Required by certain
    // older drivers for synchronization.
    // TODO: Remove this when we drop support for HWC 1.0.
    virtual status_t compositionComplete() = 0;
#endif

    // Inform the surface that GLES composition is complete for this frame, and
    // the surface should make sure that HWComposer has the correct buffer for
@@ -74,6 +76,10 @@ public:

    virtual void resizeBuffers(const uint32_t w, const uint32_t h) = 0;

#ifdef USE_HWC2
    virtual const sp<Fence>& getClientTargetAcquireFence() const = 0;
#endif

protected:
    DisplaySurface() {}
    virtual ~DisplaySurface() {}
Loading