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

Commit fd465150 authored by Ady Abraham's avatar Ady Abraham Committed by Android (Google) Code Review
Browse files

Merge changes from topic "setframerate_tv" into main

* changes:
  libnativedisplay: plumb setFrameRate to SurfaceTexure
  libnativedisplay: Introduce SurfaceTextureListener
parents d5fd0d95 d5e8e276
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -200,6 +200,7 @@ aconfig_declarations {

cc_aconfig_library {
    name: "libguiflags",
    host_supported: true,
    vendor_available: true,
    aconfig_declarations: "libgui_flags",
}
+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ cc_library_shared {
        "libGLESv2",
    ],

    static_libs: ["libguiflags"],

    export_header_lib_headers: ["jni_headers"],

    header_libs: [
+45 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <android/hardware_buffer.h>
#include <gui/BufferQueueDefs.h>
#include <gui/ConsumerBase.h>
#include <gui/Flags.h>
#include <gui/IGraphicBufferProducer.h>
#include <sys/cdefs.h>
#include <system/graphics.h>
@@ -290,6 +291,20 @@ public:
     */
    void releaseConsumerOwnership();

    /**
     * Interface for SurfaceTexture callback(s).
     */
    struct SurfaceTextureListener : public RefBase {
        virtual void onFrameAvailable(const BufferItem& item) = 0;
        virtual void onSetFrameRate(float frameRate, int8_t compatibility,
                                    int8_t changeFrameRateStrategy) = 0;
    };

    /**
     * setSurfaceTextureListener registers a SurfaceTextureListener.
     */
    void setSurfaceTextureListener(const sp<SurfaceTextureListener>&);

protected:
    /**
     * abandonLocked overrides the ConsumerBase method to clear
@@ -334,6 +349,14 @@ protected:
     */
    void computeCurrentTransformMatrixLocked();

    /**
     * onSetFrameRate Notifies the consumer of a setFrameRate call from the producer side.
     */
#if FLAG_BQ_SET_FRAME_RATE
    void onSetFrameRate(float frameRate, int8_t compatibility,
                        int8_t changeFrameRateStrategy) override;
#endif

    /**
     * The default consumer usage flags that SurfaceTexture always sets on its
     * BufferQueue instance; these will be OR:d with any additional flags passed
@@ -465,8 +488,30 @@ protected:
     */
    ImageConsumer mImageConsumer;

    /**
     * mSurfaceTextureListener holds the registered SurfaceTextureListener.
     * Note that SurfaceTexture holds the lister with an sp<>, which means that the listener
     * must only hold a wp<> to SurfaceTexture and not an sp<>.
     */
    sp<SurfaceTextureListener> mSurfaceTextureListener;

    friend class ImageConsumer;
    friend class EGLConsumer;

private:
    // Proxy listener to avoid having SurfaceTexture directly implement FrameAvailableListener as it
    // is extending ConsumerBase which also implements FrameAvailableListener.
    class FrameAvailableListenerProxy : public ConsumerBase::FrameAvailableListener {
    public:
        FrameAvailableListenerProxy(const wp<SurfaceTextureListener>& listener)
              : mSurfaceTextureListener(listener) {}

    private:
        void onFrameAvailable(const BufferItem& item) override;

        const wp<SurfaceTextureListener> mSurfaceTextureListener;
    };
    sp<FrameAvailableListenerProxy> mFrameAvailableListenerProxy;
};

// ----------------------------------------------------------------------------
+40 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <system/window.h>
#include <utils/Trace.h>

#include <com_android_graphics_libgui_flags.h>

namespace android {

// Macros for including the SurfaceTexture name in log messages
@@ -491,4 +493,42 @@ sp<GraphicBuffer> SurfaceTexture::dequeueBuffer(int* outSlotid, android_dataspac
    return buffer;
}

void SurfaceTexture::setSurfaceTextureListener(
        const sp<android::SurfaceTexture::SurfaceTextureListener>& listener) {
    SFT_LOGV("setSurfaceTextureListener");

    Mutex::Autolock _l(mMutex);
    mSurfaceTextureListener = listener;
    if (mSurfaceTextureListener != nullptr) {
        mFrameAvailableListenerProxy =
                sp<FrameAvailableListenerProxy>::make(mSurfaceTextureListener);
        setFrameAvailableListener(mFrameAvailableListenerProxy);
    } else {
        mFrameAvailableListenerProxy.clear();
    }
}

void SurfaceTexture::FrameAvailableListenerProxy::onFrameAvailable(const BufferItem& item) {
    const auto listener = mSurfaceTextureListener.promote();
    if (listener) {
        listener->onFrameAvailable(item);
    }
}

#if FLAG_BQ_SET_FRAME_RATE
void SurfaceTexture::onSetFrameRate(float frameRate, int8_t compatibility,
                                    int8_t changeFrameRateStrategy) {
    SFT_LOGV("onSetFrameRate: %.2f", frameRate);

    auto listener = [&] {
        Mutex::Autolock _l(mMutex);
        return mSurfaceTextureListener;
    }();

    if (listener) {
        listener->onSetFrameRate(frameRate, compatibility, changeFrameRateStrategy);
    }
}
#endif

} // namespace android