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

Commit b5c3de52 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I0fd6b4eb,I2523de43

* changes:
  surfaceflinger: Create SurfaceFlingerBE class
  SF: Add CompositionInfo to LayerBE
parents 236c2711 105b7dcf
Loading
Loading
Loading
Loading
+22 −22
Original line number Diff line number Diff line
@@ -109,14 +109,14 @@ void BufferLayer::useEmptyDamage() {
}

bool BufferLayer::isProtected() const {
    const sp<GraphicBuffer>& buffer(getBE().mBuffer);
    const sp<GraphicBuffer>& buffer(getBE().compositionInfo.mBuffer);
    return (buffer != 0) &&
            (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
}

bool BufferLayer::isVisible() const {
    return !(isHiddenByPolicy()) && getAlpha() > 0.0f &&
            (getBE().mBuffer != NULL || getBE().mSidebandStream != NULL);
            (getBE().compositionInfo.mBuffer != NULL || getBE().compositionInfo.hwc.sidebandStream != NULL);
}

bool BufferLayer::isFixedSize() const {
@@ -172,7 +172,7 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip,
                         bool useIdentityTransform) const {
    ATRACE_CALL();

    if (CC_UNLIKELY(getBE().mBuffer == 0)) {
    if (CC_UNLIKELY(getBE().compositionInfo.mBuffer == 0)) {
        // the texture has not been created yet, this Layer has
        // in fact never been drawn into. This happens frequently with
        // SurfaceView because the WindowManager can't know when the client
@@ -250,8 +250,8 @@ void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip,
        }

        // Set things up for texturing.
        mTexture.setDimensions(getBE().mBuffer->getWidth(),
                               getBE().mBuffer->getHeight());
        mTexture.setDimensions(getBE().compositionInfo.mBuffer->getWidth(),
                               getBE().compositionInfo.mBuffer->getHeight());
        mTexture.setFiltering(useFiltering);
        mTexture.setMatrix(textureMatrix);

@@ -387,8 +387,8 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime
        // mSidebandStreamChanged was true
        mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
        // replicated in LayerBE until FE/BE is ready to be synchronized
        getBE().mSidebandStream = mSidebandStream;
        if (getBE().mSidebandStream != NULL) {
        getBE().compositionInfo.hwc.sidebandStream = mSidebandStream;
        if (getBE().compositionInfo.hwc.sidebandStream != NULL) {
            setTransactionFlags(eTransactionNeeded);
            mFlinger->setTransactionFlags(eTraversalNeeded);
        }
@@ -422,7 +422,7 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime
    // Capture the old state of the layer for comparisons later
    const State& s(getDrawingState());
    const bool oldOpacity = isOpaque(s);
    sp<GraphicBuffer> oldBuffer = getBE().mBuffer;
    sp<GraphicBuffer> oldBuffer = getBE().compositionInfo.mBuffer;

    if (!allTransactionsSignaled()) {
        mFlinger->signalLayerUpdate();
@@ -499,11 +499,11 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime
    }

    // update the active buffer
    getBE().mBuffer =
            mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().mBufferSlot);
    getBE().compositionInfo.mBuffer =
            mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot);
    // replicated in LayerBE until FE/BE is ready to be synchronized
    mActiveBuffer = getBE().mBuffer;
    if (getBE().mBuffer == NULL) {
    mActiveBuffer = getBE().compositionInfo.mBuffer;
    if (getBE().compositionInfo.mBuffer == NULL) {
        // this can only happen if the very first buffer was rejected.
        return outDirtyRegion;
    }
@@ -540,15 +540,15 @@ Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime
    }

    if (oldBuffer != NULL) {
        uint32_t bufWidth = getBE().mBuffer->getWidth();
        uint32_t bufHeight = getBE().mBuffer->getHeight();
        uint32_t bufWidth = getBE().compositionInfo.mBuffer->getWidth();
        uint32_t bufHeight = getBE().compositionInfo.mBuffer->getHeight();
        if (bufWidth != uint32_t(oldBuffer->width) ||
            bufHeight != uint32_t(oldBuffer->height)) {
            recomputeVisibleRegions = true;
        }
    }

    mCurrentOpacity = getOpacityForFormat(getBE().mBuffer->format);
    mCurrentOpacity = getOpacityForFormat(getBE().compositionInfo.mBuffer->format);
    if (oldOpacity != isOpaque(s)) {
        recomputeVisibleRegions = true;
    }
@@ -611,13 +611,13 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)
    }

    // Sideband layers
    if (getBE().mSidebandStream.get()) {
    if (getBE().compositionInfo.hwc.sidebandStream.get()) {
        setCompositionType(hwcId, HWC2::Composition::Sideband);
        ALOGV("[%s] Requesting Sideband composition", mName.string());
        error = hwcLayer->setSidebandStream(getBE().mSidebandStream->handle());
        error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
        if (error != HWC2::Error::None) {
            ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
                  getBE().mSidebandStream->handle(), to_string(error).c_str(),
                  getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
                  static_cast<int32_t>(error));
        }
        return;
@@ -641,14 +641,14 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)

    uint32_t hwcSlot = 0;
    sp<GraphicBuffer> hwcBuffer;
    hwcInfo.bufferCache.getHwcBuffer(getBE().mBufferSlot,
                                     getBE().mBuffer, &hwcSlot, &hwcBuffer);
    hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot,
                                     getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer);

    auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
    error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
    if (error != HWC2::Error::None) {
        ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
              getBE().mBuffer->handle, to_string(error).c_str(),
              getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
              static_cast<int32_t>(error));
    }
}
@@ -656,7 +656,7 @@ void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice)
bool BufferLayer::isOpaque(const Layer::State& s) const {
    // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
    // layer's opaque flag.
    if ((getBE().mSidebandStream == nullptr) && (getBE().mBuffer == nullptr)) {
    if ((getBE().compositionInfo.hwc.sidebandStream == nullptr) && (getBE().compositionInfo.mBuffer == nullptr)) {
        return false;
    }

+12 −15
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@
#include <ui/PixelFormat.h>

#include <gui/BufferItem.h>
#include <gui/BufferQueue.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>

@@ -63,9 +62,7 @@
namespace android {

LayerBE::LayerBE()
      : mBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
        mBuffer(nullptr),
        mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) {
      : mMesh(Mesh::TRIANGLE_FAN, 4, 2, 2) {
}


@@ -257,9 +254,9 @@ Rect Layer::getContentCrop() const {
    if (!mCurrentCrop.isEmpty()) {
        // if the buffer crop is defined, we use that
        crop = mCurrentCrop;
    } else if (getBE().mBuffer != NULL) {
    } else if (getBE().compositionInfo.mBuffer != NULL) {
        // otherwise we use the whole buffer
        crop = getBE().mBuffer->getBounds();
        crop = getBE().compositionInfo.mBuffer->getBounds();
    } else {
        // if we don't have a buffer yet, we use an empty/invalid crop
        crop.makeInvalid();
@@ -1002,9 +999,9 @@ uint32_t Layer::doTransaction(uint32_t flags) {
    // to the old buffer. However in the state where we don't have an old buffer
    // there is no such concern but we may still be being used as a parent layer.
    const bool resizePending = ((c.requested.w != c.active.w) || (c.requested.h != c.active.h)) &&
            (getBE().mBuffer != nullptr);
            (getBE().compositionInfo.mBuffer != nullptr);
    if (!isFixedSize()) {
        if (resizePending && getBE().mSidebandStream == NULL) {
        if (resizePending && getBE().compositionInfo.hwc.sidebandStream == nullptr) {
            flags |= eDontUpdateGeometryState;
        }
    }
@@ -1401,7 +1398,7 @@ LayerDebugInfo Layer::getLayerDebugInfo() const {
    info.mMatrix[1][0] = ds.active.transform[1][0];
    info.mMatrix[1][1] = ds.active.transform[1][1];
    {
        sp<const GraphicBuffer> buffer = getBE().mBuffer;
        sp<const GraphicBuffer> buffer = getBE().compositionInfo.mBuffer;
        if (buffer != 0) {
            info.mActiveBufferWidth = buffer->getWidth();
            info.mActiveBufferHeight = buffer->getHeight();
@@ -1759,15 +1756,15 @@ Transform Layer::getTransform() const {
        // for in the transform. We need to mirror this scaling in child surfaces
        // or we will break the contract where WM can treat child surfaces as
        // pixels in the parent surface.
        if (p->isFixedSize() && p->getBE().mBuffer != nullptr) {
        if (p->isFixedSize() && p->getBE().compositionInfo.mBuffer != nullptr) {
            int bufferWidth;
            int bufferHeight;
            if ((p->mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) == 0) {
                bufferWidth = p->getBE().mBuffer->getWidth();
                bufferHeight = p->getBE().mBuffer->getHeight();
                bufferWidth = p->getBE().compositionInfo.mBuffer->getWidth();
                bufferHeight = p->getBE().compositionInfo.mBuffer->getHeight();
            } else {
                bufferHeight = p->getBE().mBuffer->getWidth();
                bufferWidth = p->getBE().mBuffer->getHeight();
                bufferHeight = p->getBE().compositionInfo.mBuffer->getWidth();
                bufferWidth = p->getBE().compositionInfo.mBuffer->getHeight();
            }
            float sx = p->getDrawingState().active.w / static_cast<float>(bufferWidth);
            float sy = p->getDrawingState().active.h / static_cast<float>(bufferHeight);
@@ -1867,7 +1864,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet)
        layerInfo->set_z_order_relative_of(zOrderRelativeOf->sequence);
    }

    auto buffer = getBE().mBuffer;
    auto buffer = getBE().compositionInfo.mBuffer;
    if (buffer != nullptr) {
        LayerProtoHelper::writeToProto(buffer, layerInfo->mutable_active_buffer());
    }
+31 −5
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@

#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
#include <gui/BufferQueue.h>

#include <list>

@@ -66,15 +67,37 @@ class LayerBE;

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

struct CompositionInfo {
    HWC2::Composition compositionType;
    sp<GraphicBuffer> mBuffer = nullptr;
    int mBufferSlot = BufferQueue::INVALID_BUFFER_SLOT;
    struct {
        HWComposer* hwc;
        sp<Fence> fence;
        HWC2::BlendMode blendMode;
        Rect displayFrame;
        float alpha;
        FloatRect sourceCrop;
        HWC2::Transform transform;
        int z;
        int type;
        int appId;
        Region visibleRegion;
        Region surfaceDamage;
        sp<NativeHandle> sidebandStream;
        android_dataspace dataspace;
        hwc_color_t color;
    } hwc;
    struct {
        RenderEngine* renderEngine;
        Mesh* mesh;
    } renderEngine;
};

class LayerBE {
public:
    LayerBE();

    // main thread
    int mBufferSlot;
    sp<GraphicBuffer> mBuffer;
    sp<NativeHandle> mSidebandStream;

    // The mesh used to draw the layer in GLES composition mode
    Mesh mMesh;

@@ -102,6 +125,8 @@ public:
    // case we need to keep track. In non-mirror mode, a layer will have only one
    // HWCInfo. This map key is a display layerStack.
    std::unordered_map<int32_t, HWCInfo> mHwcLayers;

    CompositionInfo compositionInfo;
};

class Layer : public virtual RefBase {
@@ -339,6 +364,7 @@ public:
    void forceClientComposition(int32_t hwcId);
    bool getForceClientComposition(int32_t hwcId);
    virtual void setPerFrameData(const sp<const DisplayDevice>& displayDevice) = 0;
    void setUpFrameBuffer(const sp<const DisplayDevice>& displayDevice);

    // callIntoHwc exists so we can update our local state and call
    // acceptDisplayChanges without unnecessarily updating the device's state
+55 −51

File changed.

Preview size limit exceeded, changes collapsed.

+40 −27
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ class RenderEngine;
class EventControlThread;
class VSyncSource;
class InjectVSyncSource;
class SurfaceFlingerBE;

typedef std::function<void(const LayerVector::Visitor&)> TraverseLayersFunction;

@@ -108,12 +109,48 @@ enum {
    eTransactionMask          = 0x07
};

class SurfaceFlingerBE
{
public:
    SurfaceFlingerBE();

    // The current hardware composer interface.
    //
    // The following thread safety rules apply when accessing mHwc, either
    // directly or via getHwComposer():
    //
    // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
    //    only when switching into and out of vr. Recreating mHwc must only be
    //    done on the main thread.
    //
    // 2. When accessing mHwc on the main thread, it's not necessary to acquire
    //    mStateLock.
    //
    // 3. When accessing mHwc on a thread other than the main thread, we always
    //    need to acquire mStateLock. This is because the main thread could be
    //    in the process of destroying the current mHwc instance.
    //
    // The above thread safety rules only apply to SurfaceFlinger.cpp. In
    // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
    // destroy it, so it's always safe to access mHwc from any thread without
    // acquiring mStateLock.
    std::unique_ptr<HWComposer> mHwc;

    // The composer sequence id is a monotonically increasing integer that we
    // use to differentiate callbacks from different hardware composer
    // instances. Each hardware composer instance gets a different sequence id.
    int32_t mComposerSequenceId;
};


class SurfaceFlinger : public BnSurfaceComposer,
                       public PriorityDumper,
                       private IBinder::DeathRecipient,
                       private HWC2::ComposerCallback
{
public:
    SurfaceFlingerBE& getBE() { return mBE; }
    const SurfaceFlingerBE& getBE() const { return mBE; }

    // This is the phase offset in nanoseconds of the software vsync event
    // relative to the vsync event reported by HWComposer.  The software vsync
@@ -509,7 +546,7 @@ private:
     * H/W composer
     */

    HWComposer& getHwComposer() const { return *mHwc; }
    HWComposer& getHwComposer() const { return *getBE().mHwc; }

    /* ------------------------------------------------------------------------
     * Compositing
@@ -632,28 +669,6 @@ private:
    // access must be protected by mInvalidateLock
    volatile int32_t mRepaintEverything;

    // The current hardware composer interface.
    //
    // The following thread safety rules apply when accessing mHwc, either
    // directly or via getHwComposer():
    //
    // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
    //    only when switching into and out of vr. Recreating mHwc must only be
    //    done on the main thread.
    //
    // 2. When accessing mHwc on the main thread, it's not necessary to acquire
    //    mStateLock.
    //
    // 3. When accessing mHwc on a thread other than the main thread, we always
    //    need to acquire mStateLock. This is because the main thread could be
    //    in the process of destroying the current mHwc instance.
    //
    // The above thread safety rules only apply to SurfaceFlinger.cpp. In
    // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
    // destroy it, so it's always safe to access mHwc from any thread without
    // acquiring mStateLock.
    std::unique_ptr<HWComposer> mHwc;

    const std::string mHwcServiceName; // "default" for real use, something else for testing.

    // constant members (no synchronization needed for access)
@@ -781,13 +796,11 @@ private:
    std::atomic<bool> mVrFlingerRequestsDisplay;
    static bool useVrFlinger;
    std::thread::id mMainThreadId;
    // The composer sequence id is a monotonically increasing integer that we
    // use to differentiate callbacks from different hardware composer
    // instances. Each hardware composer instance gets a different sequence id.
    int32_t mComposerSequenceId;

    float mSaturation = 1.0f;
    bool mForceNativeColorMode = false;

    SurfaceFlingerBE mBE;
};
}; // namespace android