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

Commit d2e77f9e authored by Ricardo Cerqueira's avatar Ricardo Cerqueira Committed by Steve Kondik
Browse files

libgui: Bring back support for mHeap-based screenshots

Older graphics libraries throw a hissy fit when trying to lock
buffers for Surface-based screenshots, on at least Tegra2/3 and
Exynos4 hardware.

This patch depends on the BOARD_USE_MHEAP_SCREENSHOT board flag
and requires the ro.bq.gpu_to_cpu_unsupported property set to 1
in order to work.

[pawitp: port to Lollipop]

Change-Id: I7db955e2cdd120018e349c14290e975788e70ed3
parent cf8339b7
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -148,6 +148,18 @@ public:
            Rotation rotation,
            bool isCpuConsumer) = 0;

#ifdef USE_MHEAP_SCREENSHOT
    /* Capture the specified screen. requires READ_FRAME_BUFFER permission
     * This function will fail if there is a secure window on screen.
     */
    virtual status_t captureScreen(const sp<IBinder>& display, sp<IMemoryHeap>* heap,
            uint32_t* width, uint32_t* height,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
            uint32_t minLayerZ, uint32_t maxLayerZ,
            bool useIdentityTransform,
            Rotation rotation = eRotateNone) = 0;
#endif

    /* Clears the frame statistics for animations.
     *
     * Requires the ACCESS_SURFACE_FLINGER permission.
@@ -177,6 +189,9 @@ public:
        GET_BUILT_IN_DISPLAY,
        SET_TRANSACTION_STATE,
        AUTHENTICATE_SURFACE,
#ifdef USE_MHEAP_SCREENSHOT
        CAPTURE_SCREEN_DEPRECATED,
#endif
        GET_DISPLAY_CONFIGS,
        GET_ACTIVE_CONFIG,
        SET_ACTIVE_CONFIG,
+6 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@ namespace android {

class DisplayInfo;
class Composer;
#ifdef USE_MHEAP_SCREENSHOT
class IMemoryHeap;
#endif
class ISurfaceComposerClient;
class IGraphicBufferProducer;
class Region;
@@ -188,6 +191,9 @@ public:
            bool useIdentityTransform);

private:
#ifdef USE_MHEAP_SCREENSHOT
    sp<IMemoryHeap> mHeap;
#endif
    mutable sp<CpuConsumer> mCpuConsumer;
    mutable sp<IGraphicBufferProducer> mProducer;
    CpuConsumer::LockedBuffer mBuffer;
+4 −0
Original line number Diff line number Diff line
@@ -52,6 +52,10 @@ ifeq ($(TARGET_USES_QCOM_BSP),true)
    LOCAL_CFLAGS += -DQCOM_BSP
endif

ifeq ($(BOARD_USE_MHEAP_SCREENSHOT),true)
    LOCAL_CFLAGS += -DUSE_MHEAP_SCREENSHOT
endif

LOCAL_MODULE:= libgui

ifeq ($(TARGET_BOARD_PLATFORM), tegra)
+52 −0
Original line number Diff line number Diff line
@@ -103,6 +103,33 @@ public:
        remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
    }

#ifdef USE_MHEAP_SCREENSHOT
    virtual status_t captureScreen(
            const sp<IBinder>& display, sp<IMemoryHeap>* heap,
            uint32_t* width, uint32_t* height,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
            uint32_t minLayerZ, uint32_t maxLayerZ,
            bool useIdentityTransform,
            ISurfaceComposer::Rotation rotation)
    {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        data.writeStrongBinder(display);
        data.write(sourceCrop);
        data.writeInt32(reqWidth);
        data.writeInt32(reqHeight);
        data.writeInt32(minLayerZ);
        data.writeInt32(maxLayerZ);
        data.writeInt32(static_cast<int32_t>(useIdentityTransform));
        data.writeInt32(static_cast<int32_t>(rotation));
        remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_DEPRECATED, data, &reply);
        *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
        *width = reply.readInt32();
        *height = reply.readInt32();
        return reply.readInt32();
    }
#endif

    virtual status_t captureScreen(const sp<IBinder>& display,
            const sp<IGraphicBufferProducer>& producer,
            Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
@@ -348,6 +375,31 @@ status_t BnSurfaceComposer::onTransact(
            bootFinished();
            return NO_ERROR;
        }
#ifdef USE_MHEAP_SCREENSHOT
        case CAPTURE_SCREEN_DEPRECATED: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> display = data.readStrongBinder();
            Rect sourceCrop;
            data.read(sourceCrop);
            uint32_t reqWidth = data.readInt32();
            uint32_t reqHeight = data.readInt32();
            uint32_t minLayerZ = data.readInt32();
            uint32_t maxLayerZ = data.readInt32();
            bool useIdentityTransform = static_cast<bool>(data.readInt32());
            uint32_t rotation = data.readInt32();
            sp<IMemoryHeap> heap;
            uint32_t w, h;
            status_t res = captureScreen(display, &heap, &w, &h,
                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
                    useIdentityTransform,
                    static_cast<ISurfaceComposer::Rotation>(rotation));
            reply->writeStrongBinder(heap->asBinder());
            reply->writeInt32(w);
            reply->writeInt32(h);
            reply->writeInt32(res);
            return NO_ERROR;
        }
#endif
        case CAPTURE_SCREEN: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> display = data.readStrongBinder();
+26 −0
Original line number Diff line number Diff line
@@ -694,6 +694,14 @@ status_t ScreenshotClient::capture(
        uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == NULL) return NO_INIT;
#ifdef USE_MHEAP_SCREENSHOT
    int format = 0;
    producer->query(NATIVE_WINDOW_FORMAT,&format);
    if (format == PIXEL_FORMAT_RGBA_8888) {
        /* For some reason, this format fails badly */
        return BAD_VALUE;
    }
#endif
    return s->captureScreen(display, producer, sourceCrop,
            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
            ISurfaceComposer::eRotateNone, false);
@@ -724,6 +732,19 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
        bool useIdentityTransform, uint32_t rotation) {
    sp<ISurfaceComposer> s(ComposerService::getComposerService());
    if (s == NULL) return NO_INIT;
#ifdef USE_MHEAP_SCREENSHOT
    int ret = -1;
    mHeap = 0;
    ret = s->captureScreen(display, &mHeap, &mBuffer.width, &mBuffer.height, sourceCrop,
            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform,
            static_cast<ISurfaceComposer::Rotation>(rotation));
    if (ret == NO_ERROR) {
        mBuffer.format = PIXEL_FORMAT_RGBA_8888;
        mBuffer.stride = mBuffer.width;
        mBuffer.data = (uint8_t *)mHeap->getBase();
    }
    return ret;
#else
    sp<CpuConsumer> cpuConsumer = getCpuConsumer();

    if (mHaveBuffer) {
@@ -743,6 +764,7 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
        }
    }
    return err;
#endif
}

status_t ScreenshotClient::update(const sp<IBinder>& display,
@@ -767,12 +789,16 @@ status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
}

void ScreenshotClient::release() {
#ifdef USE_MHEAP_SCREENSHOT
    mHeap = 0;
#else
    if (mHaveBuffer) {
        mCpuConsumer->unlockBuffer(mBuffer);
        memset(&mBuffer, 0, sizeof(mBuffer));
        mHaveBuffer = false;
    }
    mCpuConsumer.clear();
#endif
}

void const* ScreenshotClient::getPixels() const {
Loading