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

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

Merge "Camera: Combine handling of deferred surface and shared surface"

parents a437457c 758c2153
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -122,5 +122,5 @@ interface ICameraDeviceUser

    void prepare2(int maxCount, int streamId);

    void setDeferredConfiguration(int streamId, in OutputConfiguration outputConfiguration);
    void finalizeOutputConfigurations(int streamId, in OutputConfiguration outputConfiguration);
}
+48 −40
Original line number Diff line number Diff line
@@ -56,12 +56,22 @@ int OutputConfiguration::getHeight() const {
    return mHeight;
}

bool OutputConfiguration::isDeferred() const {
    return mIsDeferred;
}

bool OutputConfiguration::isShared() const {
    return mIsShared;
}

OutputConfiguration::OutputConfiguration() :
        mRotation(INVALID_ROTATION),
        mSurfaceSetID(INVALID_SET_ID),
        mSurfaceType(SURFACE_TYPE_UNKNOWN),
        mWidth(0),
        mHeight(0) {
        mHeight(0),
        mIsDeferred(false),
        mIsShared(false) {
}

OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
@@ -105,42 +115,28 @@ status_t OutputConfiguration::readFromParcel(const android::Parcel* parcel) {
        return err;
    }

    // numSurfaces is the total number of surfaces for this OutputConfiguration,
    // regardless the surface is deferred or not.
    int numSurfaces = 0;
    if ((err = parcel->readInt32(&numSurfaces)) != OK) {
        ALOGE("%s: Failed to read maxSurfaces from parcel", __FUNCTION__);
    int isDeferred = 0;
    if ((err = parcel->readInt32(&isDeferred)) != OK) {
        ALOGE("%s: Failed to read surface isDeferred flag from parcel", __FUNCTION__);
        return err;
    }
    if (numSurfaces < 1) {
        ALOGE("%s: there has to be at least 1 surface per"
              " outputConfiguration", __FUNCTION__);
        return BAD_VALUE;
    }

    // Read all surfaces from parcel. If a surface is deferred, readFromPacel
    // returns error, and a null surface is put into the mGbps. We assume all
    // deferred surfaces are after non-deferred surfaces in the parcel.
    // TODO: Need better way to detect deferred surface than using error
    // return from readFromParcel.
    std::vector<sp<IGraphicBufferProducer>> gbps;
    for (int i = 0; i < numSurfaces; i++) {
        view::Surface surfaceShim;
        if ((err = surfaceShim.readFromParcel(parcel)) != OK) {
            // Read surface failure for deferred surface configuration is expected.
            if ((surfaceType == SURFACE_TYPE_SURFACE_VIEW ||
                    surfaceType == SURFACE_TYPE_SURFACE_TEXTURE)) {
                ALOGV("%s: Get null surface from a deferred surface configuration (%dx%d)",
                        __FUNCTION__, width, height);
                err = OK;
            } else {
                ALOGE("%s: Failed to read surface from parcel", __FUNCTION__);
    int isShared = 0;
    if ((err = parcel->readInt32(&isShared)) != OK) {
        ALOGE("%s: Failed to read surface isShared flag from parcel", __FUNCTION__);
        return err;
    }

    if (isDeferred && surfaceType != SURFACE_TYPE_SURFACE_VIEW &&
            surfaceType != SURFACE_TYPE_SURFACE_TEXTURE) {
        ALOGE("%s: Invalid surface type for deferred configuration", __FUNCTION__);
        return BAD_VALUE;
    }
        gbps.push_back(surfaceShim.graphicBufferProducer);
        ALOGV("%s: OutputConfiguration: gbps[%d] : %p, name %s", __FUNCTION__,
                i, gbps[i].get(), String8(surfaceShim.name).string());

    std::vector<view::Surface> surfaceShims;
    if ((err = parcel->readParcelableVector(&surfaceShims)) != OK) {
        ALOGE("%s: Failed to read surface(s) from parcel", __FUNCTION__);
        return err;
    }

    mRotation = rotation;
@@ -148,7 +144,14 @@ status_t OutputConfiguration::readFromParcel(const android::Parcel* parcel) {
    mSurfaceType = surfaceType;
    mWidth = width;
    mHeight = height;
    mGbps = std::move(gbps);
    mIsDeferred = isDeferred != 0;
    mIsShared = isShared != 0;
    for (auto& surface : surfaceShims) {
        ALOGV("%s: OutputConfiguration: %p, name %s", __FUNCTION__,
                surface.graphicBufferProducer.get(),
                String8(surface.name).string());
        mGbps.push_back(surface.graphicBufferProducer);
    }

    ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d",
            __FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType);
@@ -161,6 +164,8 @@ OutputConfiguration::OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int ro
    mGbps.push_back(gbp);
    mRotation = rotation;
    mSurfaceSetID = surfaceSetID;
    mIsDeferred = false;
    mIsShared = false;
}

status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
@@ -183,18 +188,21 @@ status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
    err = parcel->writeInt32(mHeight);
    if (err != OK) return err;

    int numSurfaces = mGbps.size();
    err = parcel->writeInt32(numSurfaces);
    err = parcel->writeInt32(mIsDeferred ? 1 : 0);
    if (err != OK) return err;

    err = parcel->writeInt32(mIsShared ? 1 : 0);
    if (err != OK) return err;

    for (int i = 0; i < numSurfaces; i++) {
    std::vector<view::Surface> surfaceShims;
    for (auto& gbp : mGbps) {
        view::Surface surfaceShim;
        surfaceShim.name = String16("unknown_name"); // name of surface
        surfaceShim.graphicBufferProducer = mGbps[i];

        err = surfaceShim.writeToParcel(parcel);
        if (err != OK) return err;
        surfaceShim.graphicBufferProducer = gbp;
        surfaceShims.push_back(surfaceShim);
    }
    err = parcel->writeParcelableVector(surfaceShims);
    if (err != OK) return err;

    return OK;
}
+12 −1
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ public:
    int                        getSurfaceType() const;
    int                        getWidth() const;
    int                        getHeight() const;
    bool                       isDeferred() const;
    bool                       isShared() const;
    /**
     * Keep impl up-to-date with OutputConfiguration.java in frameworks/base
     */
@@ -70,6 +72,8 @@ public:
                mSurfaceType == other.mSurfaceType &&
                mWidth == other.mWidth &&
                mHeight == other.mHeight &&
                mIsDeferred == other.mIsDeferred &&
                mIsShared == other.mIsShared &&
                gbpsEqual(other));
    }
    bool operator != (const OutputConfiguration& other) const {
@@ -92,7 +96,12 @@ public:
        if (mRotation != other.mRotation) {
            return mRotation < other.mRotation;
        }

        if (mIsDeferred != other.mIsDeferred) {
            return mIsDeferred < other.mIsDeferred;
        }
        if (mIsShared != other.mIsShared) {
            return mIsShared < other.mIsShared;
        }
        return gbpsLessThan(other);
    }
    bool operator > (const OutputConfiguration& other) const {
@@ -108,6 +117,8 @@ private:
    int                        mSurfaceType;
    int                        mWidth;
    int                        mHeight;
    bool                       mIsDeferred;
    bool                       mIsShared;
    // helper function
    static String16 readMaybeEmptyString16(const android::Parcel* parcel);
};
+225 −202

File changed.

Preview size limit exceeded, changes collapsed.

+28 −3
Original line number Diff line number Diff line
@@ -131,8 +131,8 @@ public:
    // Prepare stream by preallocating up to maxCount of its buffers
    virtual binder::Status prepare2(int32_t maxCount, int32_t streamId);

    // Set the deferred surface for a stream.
    virtual binder::Status setDeferredConfiguration(int32_t streamId,
    // Finalize the output configurations with surfaces not added before.
    virtual binder::Status finalizeOutputConfigurations(int32_t streamId,
            const hardware::camera2::params::OutputConfiguration &outputConfiguration);

    /**
@@ -207,6 +207,23 @@ private:

    }; // class StreamSurfaceId

    // OutputStreamInfo describes the property of a camera stream.
    class OutputStreamInfo {
    public:
        int width;
        int height;
        int format;
        android_dataspace dataSpace;
        int32_t consumerUsage;
        OutputStreamInfo() :
                width(-1), height(-1), format(-1), dataSpace(HAL_DATASPACE_UNKNOWN),
                consumerUsage(0) {}
        OutputStreamInfo(int _width, int _height, int _format, android_dataspace _dataSpace,
                int32_t _consumerUsage) :
                    width(_width), height(_height), format(_format),
                    dataSpace(_dataSpace), consumerUsage(_consumerUsage) {}
    };

private:
    /** ICameraDeviceUser interface-related private members */

@@ -228,6 +245,7 @@ private:
    // Create an output stream with surface deferred for future.
    binder::Status createDeferredSurfaceStreamLocked(
            const hardware::camera2::params::OutputConfiguration &outputConfiguration,
            bool isShared,
            int* newStreamId = NULL);

    // Set the stream transform flags to automatically rotate the camera stream for preview use
@@ -244,6 +262,11 @@ private:
    //check if format is not custom format
    static bool isPublicFormat(int32_t format);

    // Create a Surface from an IGraphicBufferProducer. Returns error if
    // IGraphicBufferProducer's property doesn't match with streamInfo
    binder::Status createSurfaceFromGbp(OutputStreamInfo& streamInfo, bool isStreamInfoValid,
            sp<Surface>& surface, const sp<IGraphicBufferProducer>& gbp);

    // IGraphicsBufferProducer binder -> Stream ID + Surface ID for output streams
    KeyedVector<sp<IBinder>, StreamSurfaceId> mStreamMap;

@@ -267,8 +290,10 @@ private:
    // Surface is configured, the stream id will be moved to mStreamMap.
    Vector<int32_t> mDeferredStreams;

    // stream ID -> outputStreamInfo mapping
    std::unordered_map<int32_t, OutputStreamInfo> mStreamInfoMap;

    static const int32_t MAX_SURFACES_PER_STREAM = 2;
    static const int32_t MAX_DEFERRED_SURFACES = 1;
};

}; // namespace android
Loading