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

Commit d8e812ce authored by Jamie Gennis's avatar Jamie Gennis Committed by Jesse Hall
Browse files

Update ANativeWindow clients for sync

This change updates the uses of ANativeWindow to use the new ANW functions that
accept and return Sync HAL fence file descriptors.

Change-Id: I3ca648b6ac33f7360e86754f924aa072f95242f6
parent f25e183a
Loading
Loading
Loading
Loading
+20 −8
Original line number Diff line number Diff line
@@ -61,14 +61,25 @@ private:
    void init();

    // ANativeWindow hooks
    static int hook_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
    static int hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);
    static int hook_lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
    static int hook_cancelBuffer(ANativeWindow* window,
            ANativeWindowBuffer* buffer, int fenceFd);
    static int hook_dequeueBuffer(ANativeWindow* window,
            ANativeWindowBuffer** buffer, int* fenceFd);
    static int hook_perform(ANativeWindow* window, int operation, ...);
    static int hook_query(const ANativeWindow* window, int what, int* value);
    static int hook_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
    static int hook_queueBuffer(ANativeWindow* window,
            ANativeWindowBuffer* buffer, int fenceFd);
    static int hook_setSwapInterval(ANativeWindow* window, int interval);

    static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
            ANativeWindowBuffer* buffer);
    static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
            ANativeWindowBuffer** buffer);
    static int hook_lockBuffer_DEPRECATED(ANativeWindow* window,
            ANativeWindowBuffer* buffer);
    static int hook_queueBuffer_DEPRECATED(ANativeWindow* window,
            ANativeWindowBuffer* buffer);

    int dispatchConnect(va_list args);
    int dispatchDisconnect(va_list args);
    int dispatchSetBufferCount(va_list args);
@@ -86,14 +97,15 @@ private:
    int dispatchUnlockAndPost(va_list args);

protected:
    virtual int cancelBuffer(ANativeWindowBuffer* buffer);
    virtual int dequeueBuffer(ANativeWindowBuffer** buffer);
    virtual int lockBuffer(ANativeWindowBuffer* buffer);
    virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
    virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd);
    virtual int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd);
    virtual int perform(int operation, va_list args);
    virtual int query(int what, int* value) const;
    virtual int queueBuffer(ANativeWindowBuffer* buffer);
    virtual int setSwapInterval(int interval);

    virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer);

    virtual int connect(int api);
    virtual int disconnect(int api);
    virtual int setBufferCount(int bufferCount);
+7 −4
Original line number Diff line number Diff line
@@ -65,12 +65,15 @@ private:
    friend class LightRefBase<FramebufferNativeWindow>;    
    ~FramebufferNativeWindow(); // this class cannot be overloaded
    static int setSwapInterval(ANativeWindow* window, int interval);
    static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer);
    static int lockBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
    static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer);
    static int dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd);
    static int queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd);
    static int query(const ANativeWindow* window, int what, int* value);
    static int perform(ANativeWindow* window, int operation, ...);

    static int dequeueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer** buffer);
    static int queueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer);
    static int lockBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer);

    framebuffer_device_t* fbDev;
    alloc_device_t* grDev;

+127 −74
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <utils/Log.h>
#include <utils/Trace.h>

#include <ui/Fence.h>

#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceTexture.h>
@@ -62,11 +64,15 @@ void SurfaceTextureClient::init() {
    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
    ANativeWindow::cancelBuffer     = hook_cancelBuffer;
    ANativeWindow::lockBuffer       = hook_lockBuffer;
    ANativeWindow::queueBuffer      = hook_queueBuffer;
    ANativeWindow::query            = hook_query;
    ANativeWindow::perform          = hook_perform;

    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
    ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
    ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
    ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;

    const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;

@@ -103,27 +109,54 @@ int SurfaceTextureClient::hook_setSwapInterval(ANativeWindow* window, int interv
}

int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window,
        ANativeWindowBuffer** buffer) {
        ANativeWindowBuffer** buffer, int* fenceFd) {
    SurfaceTextureClient* c = getSelf(window);
    return c->dequeueBuffer(buffer);
    return c->dequeueBuffer(buffer, fenceFd);
}

int SurfaceTextureClient::hook_cancelBuffer(ANativeWindow* window,
        ANativeWindowBuffer* buffer, int fenceFd) {
    SurfaceTextureClient* c = getSelf(window);
    return c->cancelBuffer(buffer, fenceFd);
}

int SurfaceTextureClient::hook_queueBuffer(ANativeWindow* window,
        ANativeWindowBuffer* buffer, int fenceFd) {
    SurfaceTextureClient* c = getSelf(window);
    return c->queueBuffer(buffer, fenceFd);
}

int SurfaceTextureClient::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
        ANativeWindowBuffer** buffer) {
    SurfaceTextureClient* c = getSelf(window);
    int fenceFd = -1;
    int result = c->dequeueBuffer(buffer, &fenceFd);
    sp<Fence> fence(new Fence(fenceFd));
    int waitResult = fence->wait(Fence::TIMEOUT_NEVER);
    if (waitResult != OK) {
        ALOGE("hook_dequeueBuffer_DEPRECATED: Fence::wait returned an "
                "error: %d", waitResult);
        return waitResult;
    }
    return result;
}

int SurfaceTextureClient::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
        ANativeWindowBuffer* buffer) {
    SurfaceTextureClient* c = getSelf(window);
    return c->cancelBuffer(buffer);
    return c->cancelBuffer(buffer, -1);
}

int SurfaceTextureClient::hook_lockBuffer(ANativeWindow* window,
int SurfaceTextureClient::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
        ANativeWindowBuffer* buffer) {
    SurfaceTextureClient* c = getSelf(window);
    return c->lockBuffer(buffer);
    return c->lockBuffer_DEPRECATED(buffer);
}

int SurfaceTextureClient::hook_queueBuffer(ANativeWindow* window,
int SurfaceTextureClient::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
        ANativeWindowBuffer* buffer) {
    SurfaceTextureClient* c = getSelf(window);
    return c->queueBuffer(buffer);
    return c->queueBuffer(buffer, -1);
}

int SurfaceTextureClient::hook_query(const ANativeWindow* window,
@@ -157,7 +190,8 @@ int SurfaceTextureClient::setSwapInterval(int interval) {
    return res;
}

int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer,
        int* fenceFd) {
    ATRACE_CALL();
    ALOGV("SurfaceTextureClient::dequeueBuffer");
    Mutex::Autolock lock(mMutex);
@@ -186,10 +220,11 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
        }
    }
    *buffer = gbuf.get();
    *fenceFd = -1;
    return OK;
}

int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) {
int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer, int fenceFd) {
    ATRACE_CALL();
    ALOGV("SurfaceTextureClient::cancelBuffer");
    Mutex::Autolock lock(mMutex);
@@ -197,6 +232,12 @@ int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) {
    if (i < 0) {
        return i;
    }
    sp<Fence> fence(new Fence(fenceFd));
    status_t err = fence->wait(Fence::TIMEOUT_NEVER);
    if (err != OK) {
        ALOGE("queueBuffer: Fence::wait returned an error: %d", err);
        return err;
    }
    mSurfaceTexture->cancelBuffer(i);
    return OK;
}
@@ -214,13 +255,13 @@ int SurfaceTextureClient::getSlotFromBufferLocked(
    return BAD_VALUE;
}

int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) {
int SurfaceTextureClient::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) {
    ALOGV("SurfaceTextureClient::lockBuffer");
    Mutex::Autolock lock(mMutex);
    return OK;
}

int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    ATRACE_CALL();
    ALOGV("SurfaceTextureClient::queueBuffer");
    Mutex::Autolock lock(mMutex);
@@ -237,6 +278,13 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
        return i;
    }

    sp<Fence> fence(new Fence(fenceFd));
    status_t err = fence->wait(Fence::TIMEOUT_NEVER);
    if (err != OK) {
        ALOGE("queueBuffer: Fence::wait returned an error: %d", err);
        return err;
    }

    // Make sure the crop rectangle is entirely inside the buffer.
    Rect crop;
    mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
@@ -244,7 +292,7 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
    ISurfaceTexture::QueueBufferOutput output;
    ISurfaceTexture::QueueBufferInput input(timestamp, crop, mScalingMode,
            mTransform);
    status_t err = mSurfaceTexture->queueBuffer(i, input, &output);
    err = mSurfaceTexture->queueBuffer(i, input, &output);
    if (err != OK)  {
        ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
    }
@@ -692,14 +740,20 @@ status_t SurfaceTextureClient::lock(
    }

    ANativeWindowBuffer* out;
    status_t err = dequeueBuffer(&out);
    int fenceFd = -1;
    status_t err = dequeueBuffer(&out, &fenceFd);
    ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
    if (err == NO_ERROR) {
        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
        err = lockBuffer(backBuffer.get());
        ALOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
                backBuffer->handle, strerror(-err));
        if (err == NO_ERROR) {
        sp<Fence> fence(new Fence(fenceFd));

        err = fence->wait(Fence::TIMEOUT_NEVER);
        if (err != OK) {
            ALOGE("Fence::wait failed (%s)", strerror(-err));
            cancelBuffer(out, fenceFd);
            return err;
        }

        const Rect bounds(backBuffer->width, backBuffer->height);

        Region newDirtyRegion;
@@ -764,7 +818,6 @@ status_t SurfaceTextureClient::lock(
        outBuffer->format = backBuffer->format;
        outBuffer->bits   = vaddr;
    }
    }
    return err;
}

@@ -778,7 +831,7 @@ status_t SurfaceTextureClient::unlockAndPost()
    status_t err = mLockedBuffer->unlock();
    ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);

    err = queueBuffer(mLockedBuffer.get());
    err = queueBuffer(mLockedBuffer.get(), -1);
    ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
            mLockedBuffer->handle, strerror(-err));

+4 −31
Original line number Diff line number Diff line
@@ -2,14 +2,15 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := SurfaceTexture_test
LOCAL_MODULE := libgui_test

LOCAL_MODULE_TAGS := tests

LOCAL_SRC_FILES := \
    Surface_test.cpp \
    CpuConsumer_test.cpp \
    SurfaceTextureClient_test.cpp \
    SurfaceTexture_test.cpp \
    Surface_test.cpp \

LOCAL_SHARED_LIBRARIES := \
	libEGL \
@@ -18,35 +19,7 @@ LOCAL_SHARED_LIBRARIES := \
	libcutils \
	libgui \
	libstlport \
	libui \
	libutils \

LOCAL_C_INCLUDES := \
    bionic \
    bionic/libstdc++/include \
    external/gtest/include \
    external/stlport/stlport \

# Build the binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
# to integrate with auto-test framework.
include $(BUILD_NATIVE_TEST)

include $(CLEAR_VARS)

LOCAL_MODULE := CpuConsumer_test

LOCAL_MODULE_TAGS := tests

LOCAL_SRC_FILES := \
    CpuConsumer_test.cpp

LOCAL_SHARED_LIBRARIES := \
	libEGL \
	libGLESv2 \
	libbinder \
	libcutils \
	libgui \
	libstlport \
	libsync \
	libui \
	libutils \

+6 −82
Original line number Diff line number Diff line
@@ -187,34 +187,7 @@ void checkPixel(const CpuConsumer::LockedBuffer &buf,
}

// Fill a YV12 buffer with a multi-colored checkerboard pattern
void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) {
    const int blockWidth = w > 16 ? w / 16 : 1;
    const int blockHeight = h > 16 ? h / 16 : 1;
    const int yuvTexOffsetY = 0;
    int yuvTexStrideY = stride;
    int yuvTexOffsetV = yuvTexStrideY * h;
    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
    int yuvTexStrideU = yuvTexStrideV;
    for (int x = 0; x < w; x++) {
        for (int y = 0; y < h; y++) {
            int parityX = (x / blockWidth) & 1;
            int parityY = (y / blockHeight) & 1;
            unsigned char intensity = (parityX ^ parityY) ? 63 : 191;
            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity;
            if (x < w / 2 && y < h / 2) {
                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity;
                if (x * 2 < w / 2 && y * 2 < h / 2) {
                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] =
                    buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] =
                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] =
                    buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] =
                        intensity;
                }
            }
        }
    }
}
void fillYV12Buffer(uint8_t* buf, int w, int h, int stride);

// Fill a RAW sensor buffer with a multi-colored checkerboard pattern.
// Assumes GRBG mosaic ordering. Result should be a grid in a 2x2 pattern
@@ -285,58 +258,13 @@ void checkBayerRawBuffer(const CpuConsumer::LockedBuffer &buf) {
    checkPixel(buf, w-1, h-1, maxR, maxG, maxB);
}

// Fill a YV12 buffer with red outside a given rectangle and green inside it.
void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride,
        const android_native_rect_t& rect) {
    const int yuvTexOffsetY = 0;
    int yuvTexStrideY = stride;
    int yuvTexOffsetV = yuvTexStrideY * h;
    int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf;
    int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2;
    int yuvTexStrideU = yuvTexStrideV;
    for (int x = 0; x < w; x++) {
        for (int y = 0; y < h; y++) {
            bool inside = rect.left <= x && x < rect.right &&
                    rect.top <= y && y < rect.bottom;
            buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64;
            if (x < w / 2 && y < h / 2) {
                bool inside = rect.left <= 2*x && 2*x < rect.right &&
                        rect.top <= 2*y && 2*y < rect.bottom;
                buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16;
                buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] =
                        inside ? 16 : 255;
            }
        }
    }
}
        const android_native_rect_t& rect);

void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) {
    const size_t PIXEL_SIZE = 4;
    for (int x = 0; x < w; x++) {
        for (int y = 0; y < h; y++) {
            off_t offset = (y * stride + x) * PIXEL_SIZE;
            for (int c = 0; c < 4; c++) {
                int parityX = (x / (1 << (c+2))) & 1;
                int parityY = (y / (1 << (c+2))) & 1;
                buf[offset + c] = (parityX ^ parityY) ? 231 : 35;
            }
        }
    }
}
void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride);

void fillRGBA8BufferSolid(uint8_t* buf, int w, int h, int stride, uint8_t r,
        uint8_t g, uint8_t b, uint8_t a) {
    const size_t PIXEL_SIZE = 4;
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < h; x++) {
            off_t offset = (y * stride + x) * PIXEL_SIZE;
            buf[offset + 0] = r;
            buf[offset + 1] = g;
            buf[offset + 2] = b;
            buf[offset + 3] = a;
        }
    }
}
        uint8_t g, uint8_t b, uint8_t a);

// Configures the ANativeWindow producer-side interface based on test parameters
void configureANW(const sp<ANativeWindow>& anw,
@@ -373,17 +301,13 @@ void produceOneFrame(const sp<ANativeWindow>& anw,
    status_t err;
    ANativeWindowBuffer* anb;
    ALOGVV("Dequeue buffer from %p", anw.get());
    err = anw->dequeueBuffer(anw.get(), &anb);
    err = native_window_dequeue_buffer_and_wait(anw.get(), &anb);
    ASSERT_NO_ERROR(err, "dequeueBuffer error: ");

    ASSERT_TRUE(anb != NULL);

    sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));

    ALOGVV("Lock buffer from %p", anw.get());
    err = anw->lockBuffer(anw.get(), buf->getNativeBuffer());
    ASSERT_NO_ERROR(err, "lockBuffer error: ");

    *stride = buf->getStride();
    uint8_t* img = NULL;

@@ -411,7 +335,7 @@ void produceOneFrame(const sp<ANativeWindow>& anw,
    ASSERT_NO_ERROR(err, "set_buffers_timestamp error: ");

    ALOGVV("Queue buffer to %p", anw.get());
    err = anw->queueBuffer(anw.get(), buf->getNativeBuffer());
    err = anw->queueBuffer(anw.get(), buf->getNativeBuffer(), -1);
    ASSERT_NO_ERROR(err, "queueBuffer error:");
};

Loading